如何使用计时器以一定间隔从NotifyIcon创建一个显示气球提示的UserControl?

问题描述

我正在创建一个用户定义的时间创建通知的应用。

基本上我使用两个WinForms

  • 数字1用于获取通知数据并创建NotificationObject类的新实例,其中包含消息,标题,到期时间等通知数据。
  • Form 2号用于跟踪通知

程序启动时,将打开Form 2号,并且有一个按钮可以打开Form 1号。当窗体1关闭时,它将通知数据保存到NotificationObject类中。 Form数字2获得NotificationObject,该数字是在Form数字1关闭时创建的,并将其添加ObservableCollection。将某些内容添加ObservableCollection时,它将创建一个具有构造函数参数UserControlDueTimeTitle的{​​{1}}。然后在Message内部,使用UserControlSystem.Threading.Timer创建通知

即使我已经设置了NotifyIcon方法来创建Callback Balloon,它也不会显示任何内容

表格1

NotifyIcon

2号表格

public partial class NotificationCreator : Form
{
    public NotificationObject ntfObj;
    
    public NotificationCreator()
    {
        InitializeComponent();
    }
    
    private void createNotification_Click(object sender,EventArgs e)
    {
        if (String.IsNullOrEmpty(timeInput.Text))
        {
            MessageBox.Show(
                "Please set the time.","Time is not set",MessageBoxButtons.OK,MessageBoxIcon.Error
            );
    
            return;
        }
    
        if (String.IsNullOrEmpty(titleInput.Text))
        {
            MessageBox.Show(
                "Please set the title.","Title is not set",MessageBoxIcon.Error
            );
    
            return;
        }
    
        if (String.IsNullOrEmpty(messageInput.Text))
        {
            MessageBox.Show(
                "Please set the message.","Message is not set",MessageBoxIcon.Error
            );
    
            return;
        }
    
        DateTime time = DateTime.Parse(timeInput.Text);
    
        DateTime dt = new DateTime(dateInput.Value.Year,dateInput.Value.Month,dateInput.Value.Day,time.Hour,time.Minute,0
        );
    
        ntfObj = new NotificationObject(dt,titleInput.Text,messageInput.Text);
    
        Close();
        dispose();
    }
    
    private void timeInput_TextChanged(object sender,EventArgs e)
    {
        if (timeInput.Text.Length == 5)
        {
            try
            {
                DateTime dummy = DateTime.Parse(timeInput.Text);
    
                if (dummy.Hour <= DateTime.Now.Hour && dummy.Minute <= DateTime.Now.Minute && dummy.Hour != 00 && dummy.Minute != 00)
                {
                    MessageBox.Show("Please set the time for future","Invalid time",MessageBoxIcon.Error);
    
                    return;
                }
    
                return;
            }
            catch
            {
                MessageBox.Show("Please set a valid time",MessageBoxIcon.Error);
                return;
            }
        }
    }
    
    private void dateInput_ValueChanged(object sender,EventArgs e)
    {
        if (dateInput.Value < DateTime.Now.AddDays(-1))
        {
            MessageBox.Show("Please set the date for future.","Invalid date",MessageBoxIcon.Error);
    
                dateInput.Value = DateTime.Now;
                    
                return;
            }
        }
    }
}

NotificationObject

public partial class TrackingPanel : Form
{
    ObservableCollection<NotificationObject> ntfList = new ObservableCollection<NotificationObject>();

    public TrackingPanel()
    {
        InitializeComponent();

        ntfList.CollectionChanged += NtfList_CollectionChanged;
    }

    private void NtfList_CollectionChanged(object sender,NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            NotificationObject ntfObj = e.NewItems[0] as NotificationObject;

            Notification ntf = new Notification(ntfObj.DueTime,ntfObj.ntfTitle,ntfObj.ntfMessage);

            ntfPanel.Controls.Add(ntf);
        }
    }

    private void TrackingPanel_Load(object sender,EventArgs e)
    {}

    private void TrackingPanel_Resize(object sender,EventArgs e)
    {
        if (WindowState == FormWindowState.Minimized)
        {}
    }

    private void createNotification_Click(object sender,EventArgs e)
    {
        NotificationCreator Tool = new NotificationCreator();
        Tool.ShowDialog();

        ntfList.Add(Tool.ntfObj);
    }
}

UserControl

/// <summary>
/// An object that represents the Notification and contains Notification information.
/// </summary>
public class NotificationObject
{
    /// <summary>
    /// Notification due time.
    /// </summary>
    public DateTime DueTime { get; set; }
    /// <summary>
    /// Title of Notification.
    /// </summary>
    public string ntfTitle { get; set; }
    /// <summary>
    /// Notification Message.
    /// </summary>
    public string ntfMessage{ get; set; }

    public NotificationObject(DateTime dueTime,string title,string message)
    {
        DueTime = dueTime;
        ntfTitle = title;
        ntfMessage = message;
    }
}

编辑

我在UserControl中使用了System.Windows.Forms.Timer,但仍然无法正常工作。

 public partial class Notification : UserControl
    {
        private readonly System.Threading.Timer timer;

        public Notification(DateTime dt,string Title,string Message)
        {
            InitializeComponent();

            this.Title.Text = Title;
            this.Message.Text = Message;

            ntfIco.Visible = false;

            timer = new System.Threading.Timer(NotificationOccurs,null,dt - DateTime.Now,TimeSpan.FromSeconds(20));
        }

        private void NotificationOccurs(object state)
        {
            ntfIco.Visible = true;

            ntfIco.ShowBalloonTip(3500,Title.Text,Message.Text,ToolTipIcon.Info);

            ntfIco.Visible = false;
        }

        private void Notification_Load(object sender,EventArgs e)
        {
            ntfPic.Image = Properties.Resources.Search_Png;
        }
    }

解决方法

从评论讨论中:

  • 请确保设置通知图标的Icon属性。

  • 使WinForms Timer与UI线程保持一致。

  • 不要在气球尖端弹出后立即将通知图标可见设置为false,否则它将关闭。

  • 让气球尖端逐渐褪色。

  • 如果要隐藏通知图标,请在BallonTipClosed事件上执行该操作。

private void Timer_Tick(object sender,EventArgs e)
{
  ntfIco.Visible = true;
  ntfIco.ShowBalloonTip(3500,Title.Text,Message.Text,ToolTipIcon.Info);
  Timer.Interval = 10 * 1000;
}
public Notification(DateTime dt,string Title,string Message)
{
  InitializeComponent();
  this.Title.Text = Title;
  this.Message.Text = Message;
  ntfIco.Visible = false;

  ntfIco.BalloonTipClosed += (sender,e) => ntfIco.Visible = false;

  Timer.Interval = (int)( dt - DateTime.Now ).TotalMilliseconds;
  Timer.Start();
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...