问题描述
基本上我使用两个WinForms
:
程序启动时,将打开Form
2号,并且有一个按钮可以打开Form
1号。当窗体1关闭时,它将通知数据保存到NotificationObject
类中。 Form
数字2获得NotificationObject
,该数字是在Form
数字1关闭时创建的,并将其添加到ObservableCollection
。将某些内容添加到ObservableCollection
时,它将创建一个具有构造函数参数UserControl
,DueTime
和Title
的{{1}}。然后在Message
内部,使用UserControl
和System.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();
}