【问题标题】:how to change "this.ShowInTaskBar" for a "form.ShowDialog()" while keeping it open?如何在保持打开状态的同时为“form.ShowDialog()”更改“this.ShowInTaskBar”?
【发布时间】:2010-03-06 00:58:11
【问题描述】:

如果您在具有 2 个表单的全新 winform 应用程序中运行此代码的 sn-p(将其放入 form1)

    private void Form1_Load(object sender, EventArgs e)
    {
        Form2 newForm = new Form2();
        Button b = new Button();
        newForm.Controls.Add(b);
        b.Click += new EventHandler(click);
        this.Show();
        newForm.ShowDialog();

    }

    private void click(object sender, EventArgs e)
    {
        ((Form)((Control)sender).Parent).ShowInTaskbar = false;
    }

然后你点击新表单上的按钮(应该是form2),form2会关闭。

如何保持打开状态?

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    这是不可能的。实际上,我在 Microsoft 的反馈网站上提交了一个 bug report 的相关信息,但他们却把它扔给了我。

    诚然,这是一个很难解决的问题,更改属性需要 Windows 窗体从头开始重新创建窗口,因为它由样式标志控制。您只能在带有 dwExStyle 参数的 CreateWindowEx() 调用中指定的类型。根据 ShowDialog() 方法调用的要求,重新创建窗口使其难以保持模态。

    Windows 窗体可以解决很多 User32 限制。但不是那个。

    【讨论】:

    • @Fredou:你说的很对,是娘娘腔。但为提出它而受到赞誉。不过,请尽量遵循常见的 UI 准则,对话框不应设置其 ShowInTaskbar 属性。
    【解决方案2】:

    在 ShowDialog() 之前将 ShowInTaskbar 设置为 false 以使其保持打开状态;

    private void Form1_Load(object sender, EventArgs e)
    {
        Form2 newForm = new Form2();
        Button b = new Button();
        newForm.Controls.Add(b);
        b.Click += new EventHandler(click);
        this.Show();
    
        // add this line of code...
        newForm.ShowInTaskbar = false; 
    
        newForm.ShowDialog();
    
    }
    
    private void click(object sender, EventArgs e)
    {
        ((Form)((Control)sender).Parent).ShowInTaskbar = false;
    }
    

    或者只是不要使第二种形式成为模态。这也有效。

    private void Form1_Load(object sender, EventArgs e)
    {
        Form2 newForm = new Form2();
        Button b = new Button();
        newForm.Controls.Add(b);
        b.Click += new EventHandler(click);
        this.Show();
    
        newForm.Show();
    }
    

    我不知道这里的具体机制,但很明显正在发生的事情是更改标志(实际上更改了一个或多个 WS_EX_xxx 窗口样式)导致 ShowDialog() 的模态泵退出。这反过来又导致您(最终!)退出 Form1_Load,然后您的 newForm 超出范围并被销毁。

    所以你的问题是 ShowDialog() 和你没有准备好 ShowDialog() 退出的事实。

    现在一个模态不应该首先显示任务栏图标,实际上应该只有一个应用程序的任务栏图标和所有它的模态形式,因为当一个模态窗体正在运行,主窗体无论如何都被禁用。当主窗体最小化时,它拥有的所有模态窗体都将被隐藏,等等。

    因此,如果您真的希望第二种形式是模态的,您不应该让用户能够给它一个任务栏图标。如果使用 ShowDialog() 只是测试代码,那么不用担心。当表单在主应用程序泵上运行时,问题就会消失。

    【讨论】:

    • 这是一个示例,用户可以从 form2 中的菜单更改该变量的状态,这不是自动设置
    • @Fredu:那是你的问题。在窗口已经创建之后更改这个 live 是没有意义的。在任何情况下,如果第二种形式不是模态的,当您更改标志时它不会消失
    • 看看我自己的答案,寻找一个丑陋的解决方法,我不制定规范,我实施它们:-(
    • @Fredou:如果你告诉我什么应用程序。我很乐意提交有关滥用任务栏图标的错误报告;)
    • 事情是,模式形式可以在任务栏或托盘或两者中
    【解决方案3】:

    你的问题对我来说不是很清楚。无论如何,newForm 表单显示为模式对话框,这意味着它会阻止用户使用父表单,直到它关闭。模态对话框通常有一些按钮会自动关闭它们,将OKCancel 返回到调用表单(作为ShowDialog 的返回值)。这是使用DialogResult property 完成的,因此如果为您的按钮设置了此属性,这可能是您单击它时模态表单关闭的原因。

    如果您想以允许用户同时使用它们的方式显示更多表单,则需要使用无模式对话框。这是good overview article on MSDN

    【讨论】:

    • 我的问题是,如何保留设置为显示为对话框的表单并将其从任务栏中删除,而不会自动关闭表单
    【解决方案4】:

    怎么......我的......这是一个丑陋的黑客

    这个作品

        private void Form1_Load(object sender, EventArgs e)
        {
            Form2 newForm = new Form2();
            Button b = new Button();
            newForm.Controls.Add(b);
            b.Click += new EventHandler(click);
            newForm.FormClosed += new FormClosedEventHandler(form2_closed);
            newForm.FormClosing += new FormClosingEventHandler(form2_closing);
            this.Show();
            do
            {
              newForm.ShowDialog();
            } while (newForm.IsDisposed == false );               
        }
    
        private void click(object sender, EventArgs e)
        {
            ((Form)((Control)sender).Parent).ShowInTaskbar = !((Form)((Control)sender).Parent).ShowInTaskbar;
        }
    
        private void form2_closed(object sender, FormClosedEventArgs e)
        {
            ((Form)sender).Dispose();
        }
    
        private void form2_closing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.None)
                e.Cancel = true;
        }
    

    【讨论】:

    • 不,这是错误的。模态表单和任务栏图标不混合。使用其中一种,但不能同时使用。
    • 我同意你的观点,但我不做具体说明,我希望我有时间
    • 问题不仅在于您违反了约定,还在于您依赖于未定义或错误的行为。例如,您可能会发现这不适用于所有版本的 Windows。
    猜你喜欢
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-07
    • 2018-04-08
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多