c#显示没有焦点的通知表单

本文关键字:通知 表单 焦点 显示 | 更新日期: 2023-09-27 18:17:01

所以,我们认为在我们的聊天应用程序中添加一些Toast功能是一个好主意,它实际上工作得很好,但是,当表单显示时,它会短暂地窃取焦点,这可能会使聊天输入框(当你输入它时)闪烁或清除所有文本(因为焦点被窃取了)。

我已经审查了这个网站上的几个线程,关于如何通过覆盖createparms甚至做showwithoutactivating或一些这样的事情来阻止它的发生,但它的工作不太正确。

这是我所拥有的(我为所有的评论道歉,我们的老板希望所有的东西都记录下来):

 public partial class ToastForm : DevComponents.DotNetBar.Metro.MetroForm
{
    #region Variables
    private readonly int _location;
    /// <summary>
    /// The list of currently open ToastForms.
    /// </summary>
    private static readonly List<ToastForm> OpenForms = new List<ToastForm>();
    /// <summary>
    /// Set the window to top most
    /// </summary>
    private const int WsExTopmost = 0x00000008;
    #endregion // Variables

    #region Constructors
    /// <summary>
    /// Creates a new ToastForm object that is displayed for the specified length of time.
    /// </summary>
    /// <param name="lifeTime">
    /// The length of time, in milliseconds, that the form will be displayed.
    /// </param>
    /// <param name="title">title of tooltip</param>
    /// <param name="message">message for tooltip</param>
    /// <param name="location">Location:  0 = top left, 1 = top right, 2 = bottom left, 3 = bottom right</param>
    public ToastForm(int lifeTime,
                     string title,
                     string message,
                     int location)
    {
        InitializeComponent();

        // Set the time for which the form should be displayed and the message to display.
        lifeTimer.Interval = lifeTime;
        tooltipTitle.Text =
            string.Format("<b><font size='"+6'"><i>New</i><font color='"#B02B2C'">{0}</font></font></b>",
                          title);
        tooltipText.Text = message;
        _location = location;
    }
    /// <summary>
    /// Do not activate the window just show it
    /// </summary>
    protected override bool ShowWithoutActivation
    {
        get { return true; }
    }
    /// <summary>
    /// Force the ExStyle to be TopMost
    /// </summary>
    protected override CreateParams CreateParams
    {
        get
        {
            var param = base.CreateParams;
            param.ExStyle |= WsExTopmost; // make the form topmost
            return param;
        }
    }
    #endregion // Constructors

    #region Event Handlers
    /// <summary>
    /// Do this when the form loads
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ToastFormLoad(object sender,
                               EventArgs e)
    {
        switch (_location)
        {
            case 0: // top left corner of screen
                Location = new Point(0,
                                     0);
                break;
            case 1: // top right corner of screen
                Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - Width - 5,
                                     0);
                break;
            case 2: // bottom left corner of screen
                Location = new Point(0,
                                     Screen.PrimaryScreen.WorkingArea.Height - Height - 5);
                break;
            case 3: // bottom right corner of screen
                Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - Width - 5,
                                     Screen.PrimaryScreen.WorkingArea.Height - Height - 5);
                break;
        }
        // Move each open form upwards to make room for this one.
        foreach (var openForm in OpenForms)
        {
            switch (_location)
            {
                case 0:
                case 1:
                    openForm.Top += Height + 5;
                    break;
                case 2:
                case 3:
                    openForm.Top -= Height + 5;
                    break;
            }
        }
        OpenForms.Add(this);
        lifeTimer.Start();
    }
    /// <summary>
    /// Happens when the form closes
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ToastFormFormClosed(object sender,
                                     FormClosedEventArgs e)
    {
        // Move down any open forms above this one.
        foreach (var openForm in OpenForms.TakeWhile(openForm => openForm != this))
        {
            switch (_location)
            {
                case 0:
                    openForm.Top -= Height + 5;
                    break;
                case 1:
                    openForm.Top -= Height + 5;
                    break;
                case 2:
                    openForm.Top += Height + 5;
                    break;
                case 3:
                    openForm.Top += Height + 5;
                    break;
            }
        }
        // Remove this form from the open form list.
        OpenForms.Remove(this);
    }
    /// <summary>
    /// If the tooltip has expired
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void LifeTimerTick(object sender,
                               EventArgs e)
    {
        // The form's lifetime has expired.
        Close();
    }
    #endregion // Event Handlers
    #region Methods
    /// <summary>
    /// Quickly close the tooltip
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void TooltipCancelClick(object sender,
                                    EventArgs e)
    {
        lifeTimer.Interval = 1;
    }
    #endregion
}

我们根据主表单中的事件触发这些弹出窗口(比如当一个新的公共消息进来时,通过引用另一个类中的命令(在主表单的类中节省空间):

class ToastControl
{
    public static int SliceCount { get; private set; }
    internal static void ShowAlert(string msg, string title, Font fnt)
    {
        switch (Settings.Default.PopUpSide)
        {
            case 0:
                AlertTopLeft(msg, title, fnt);
                break;
            case 1:
                AlertTopRight(msg, title, fnt);
                break;
            case 2:
                AlertBottomLeft(msg, title, fnt);
                break;
            case 3:
                AlertBottomRight(msg, title, fnt);
                break;
            default:
                 AlertBottomRight(msg, title, fnt);
                break;
        }
    }
    internal static void AlertBottomRight(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        var slice = new ToastForm(5000,
                                  title,
                                  msg, 3)
        {
            Height = (25 + 82) + ((int)(msg.Length / fnt.Size)) * 2
        };
        slice.Show();
    }
   internal static void AlertBottomLeft(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        var slice = new ToastForm(5000,
                                  title,
                                  msg,
                                  2)
                                  {
                                      Height = (25 + 82) + ((int)(msg.Length / fnt.Size)) * 2
                                  };
        slice.Show();
    }
    internal static void AlertTopLeft(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        var slice = new ToastForm(5000,
                                  title,
                                  msg, 0)
        {
            Height = (25 + 82) + ((int)(msg.Length / fnt.Size)) * 2
        };
        slice.Show();
    }
    internal static void AlertTopRight(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        var slice = new ToastForm(5000,
                                  title,
                                  msg, 1)
        {
            Height = (25 + 82) + ((int)(msg.Length / fnt.Size)) * 2
        };
        slice.Show();
    }
}

和这个类调用的一个例子:

if (Settings.Default.PopUpEnabledChat)
            {
                if (!(Settings.Default.NoAlerts))
                    ToastControl.ShowAlert(string.Format("{0}: {1}", user.Nick, description.Replace("'r",
                                                              "").Replace("'n",
                                                                          "").Replace("'0",
                                                                                      "")), channel, Font);
            }

我怎样才能得到这个通知表单显示从未窃取焦点从主应用程序?

c#显示没有焦点的通知表单

看起来解决方案是做几乎我所做的,除了我需要添加以下通知表单:

/// <summary>
    /// Do not activate the window just show it
    /// </summary>
    protected override bool ShowWithoutActivation
    {
        get { return true; }
    }
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x00000008; //WS_EX_TOPMOST 
            return cp;
        }
    } 

并更改Toast Control类使用'Visible'而不是'。秀":

 internal static void AlertBottomRight(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        new ToastForm(5000,
                      title,
                      msg,
                      3) {
                             Height = (25 + 82) + ((int) (msg.Length / fnt.Size)) * 2,
                             Visible = true
                         };
    }
    internal static void AlertBottomLeft(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        new ToastForm(5000,
                      title,
                      msg,
                      2) {
                             Height = (25 + 82) + ((int) (msg.Length / fnt.Size)) * 2,
                             Visible = true
                         };
    }
    internal static void AlertTopLeft(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        new ToastForm(5000,
                      title,
                      msg,
                      0) {
                             Height = (25 + 82) + ((int) (msg.Length / fnt.Size)) * 2,
                             Visible = true
                         };
    }
    internal static void AlertTopRight(string msg, string title, Font fnt)
    {
        SliceCount += 1;
        new ToastForm(5000,
                      title,
                      msg,
                      1) {
                             Height = (25 + 82) + ((int) (msg.Length / fnt.Size)) * 2,
                             Visible = true
                         };
    }

现在当通知显示时,它们不会窃取焦点,并且它们在其他窗口的顶部显示得很好:)