我的Windows窗体应用程序(C#)有一个奇怪的问题。我的项目中有一个带有NotifyIcon的表单(Form1)和另一个表单(Form2)。 Form1有一些代码基本上做了一些XML解析,并在Form2上添加了一堆LinkLabel。这一切都很好。
在NotifyIcon上,我有一个带有EventHandler的ContextMenu MenuItem(称为“Refresh”),基本上可以通过XML解析命令运行。我还在NotifyIcon上有一个MouseDoubleClick命令,当双击系统托盘图标时,它会打开Form2(使用ShowDialog())来显示LinkLabels的链接。这也很好。
我在Form2上有一个Button Control(称为“Close”),它正在使用这个EventHandler代码:
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
关闭Form2。这也很好。
但是,根据Form1的NotifyIcon上的“刷新”ContextMenu MenuItem被击中的次数,这是在Form2关闭之前必须按下Form2上的“关闭”按钮控件的次数。例如,如果用户三次击中Form1上的“刷新”MenuItem,则必须在Form2上按三次“关闭”按钮控件。它几乎就像Form2明显关闭一样,但代码似乎并没有意识到它已经关闭了。
我是Windows Form开发的新手,所以也许这是我不知道的生命周期事情。任何帮助将不胜感激。
EDIT。我会尝试发布相应的代码:
//NotifyIcon Form (Form1)
//ico is the ID of the NotifyIcon
public partial class TrayIcon : Form
{
Message msg = new Message(); //Form2
ContextMenu contextMenu = new ContextMenu();
public TrayIcon()
{
InitializeComponent();
}
private void TrayIcon_Load(object sender, EventArgs e)
{
contextMenu.MenuItems.Clear();
contextMenu.MenuItems.Add(0, new MenuItem("Refresh", new System.EventHandler(ico_Refresh)));
ico.DoubleClick += new MouseEventHandler(ico_ShowMsg);
DoXmlParsing();
}
private void ico_Refresh(object Sender, EventArgs e)
{
TrayIcon_Load(null, null);
}
private void ico_ShowMsg(object Sender, MouseEventHandler e)
{
if (msg.Visible == false)
msg.ShowDialog();
}
}
在Form2(消息)上我有一个带有此Click处理程序代码的按钮:
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
//I have also tried:
if (this.Visible)
this.Hide();
}
答案 0 :(得分:9)
我认为这一行是问题所在:
ico.DoubleClick += new MouseEventHandler(ico_ShowMsg);
您继续为双击添加更多事件处理程序,但从不删除它们(因为在TrayIcon_Load
中调用了ico_Refresh
。
关闭对话框后,再次调用.ShowDialog()
,但多次添加此事件处理程序。
答案 1 :(得分:2)
根据您的解释,您的Refresh MenuItem似乎会在之前的表单中启动表单2的新实例。
你能否展示一下Refresh menuitem背后的代码?
答案 2 :(得分:2)
我认为你每次都在创建一个Form2的新实例,所以你必须关闭每个实例......
您可以发布NotifyIcon MouseDoubleClick事件处理程序的代码吗?
更新:好的,我知道,那是因为每次你点击菜单项时,都会为事件添加一个新的处理程序(menuitem和notifyicon):没有什么可以阻止重复的处理程序,所以处理程序被多次调用。由于表格以模态显示,因此关闭,然后重新打开,然后关闭......
您只需要注册一次处理程序(例如在构造函数中)。此外,您可以在ico_Refresh
中调用DoXmlParsing答案 3 :(得分:2)
我不是100%肯定你的问题,因为没有代码,但对我来说听起来就像你在启动Form2时使用类似下面的东西:
Form2 f = new Form2();
f.Show();
如果是这种情况,并且表单始终显示在完全相同的位置,那不是你必须多次关闭“它”,而是它们中的许多实际存在且可见。尝试移动表单并查看其下方是否有任何形式。 :)
我推荐的是将一个Form2类实例保留在内存中,直到您的应用程序退出时才关闭。根据需要显示和隐藏它。