代码之家  ›  专栏  ›  技术社区  ›  Kris B

Windows窗体:关闭,但不关闭

  •  1
  • Kris B  · 技术社区  · 15 年前

    我的Windows窗体应用程序(C)有一个奇怪的问题。我的项目中有一个带有通知图标的表单(Form1)和另一个表单(Form2)。Form1有一些基本上可以进行XML解析的代码,并在Form2上添加了一些链接标签。这一切都很好。

    在notifyicon上,我有一个contextmenu菜单项(称为“refresh”),它有一个eventhandler,基本上可以通过命令上的XML解析运行。在notifyIcon上,我还有一个mousedoubleclick命令,当双击系统托盘图标时,它会打开Form2(使用showDialog())来显示链接标签的链接。这也很有效。

    我在Form2上有一个按钮控件(称为“Close”),它使用以下事件处理程序代码:

    private void btnClose_Click(object sender, EventArgs e)
    {
        this.Close();
    }
    

    关闭窗体2。这也很有效。

    但是,根据在Form1的NotifyIcon上单击“刷新”ContextMenu菜单项的次数,这是在Form2关闭之前必须按下Form2上“关闭”按钮控件的次数。例如,如果用户三次点击Form1上的“刷新”菜单项,他们必须三次点击Form2上的“关闭”按钮控件。它几乎像Form2明显关闭了,但代码似乎没有意识到它是关闭的。

    我对Windows窗体的开发还不熟悉,所以可能这是我不知道的生命周期问题。任何帮助都将不胜感激。

    编辑。我将尝试发布适当的代码:

    //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(消息)上,我有一个按钮,上面有这个点击处理程序代码:

    private void btnClose_Click(object sender, EventArgs e)
    {
        this.Close();
    
        //I have also tried:
        if (this.Visible)
            this.Hide();
    }
    
    4 回复  |  直到 15 年前
        1
  •  9
  •   recursive    15 年前

    我认为问题出在这一行:

    ico.DoubleClick += new MouseEventHandler(ico_ShowMsg);
    

    您不断地向双击添加更多的事件处理程序,但从不删除它们(因为 TrayIcon_Load 被调用 ico_Refresh .

    关闭对话框后, .ShowDialog() 再次调用,但多次添加此事件处理程序。

        2
  •  2
  •   ZippyV    15 年前

    从您的解释来看,您的刷新菜单项似乎比前一个表单启动了表单2的新实例。

    你能把刷新菜单项后面的代码显示出来吗?

        3
  •  2
  •   John Rudy    15 年前

    我对你的问题不是百分之百的肯定,因为没有代码,但在我看来,当Form2启动时,你在使用类似以下的东西:

    Form2 f = new Form2();
    f.Show();
    

    如果是这样的话,并且表单总是出现在完全相同的位置,那不是说你必须多次关闭“it”,而是说其中有许多实际上存在并且可见。尝试移动窗体并查看其下是否有任何内容。:)

    我建议您使用一个留在内存中的form2类实例,直到应用程序退出后才关闭。根据需要显示和隐藏。

        4
  •  2
  •   Thomas Levesque    15 年前

    我想你每次都在创建一个新的Form2实例,所以你必须关闭每个实例…

    你能发布notifyicon mousedoubleclick事件处理程序的代码吗?


    更新:好的,我明白了,这是因为每次单击菜单项时,它都会向事件添加一个新的处理程序(menu item和notifyicon):没有什么可以防止重复的处理程序,所以该处理程序会被多次调用。由于窗体是以模态显示的,因此它关闭,然后重新打开,然后关闭…

    您只需要注册一次处理程序(例如,在构造函数中)。另外,您可以在ICO刷新中调用DoxmlParsing