c# - 如何将所有应用程序设置为 Form.showDialog() 的所有者

c# - How to set all the application as the owner of Form.showDialog()

我有一个 Windows 桌面应用程序,它实现了自动更新方法。我想显示一个自定义表单(因为我需要更改按钮文本),在检测到新更新时询问用户是否要下载新版本并且我想“阻止”中的所有输入操作桌面应用程序,直到用户做出选择。

在阅读 Form.ShowDialog() 文档和此处的几个主题后说“ShowDialog() 没有使我的 windows 模态”和几个回答“您需要正确设置所有者”我仍然不明白如何设置这个所有者。当然,如果我做两个表格,第一个显示第二个,我可以“阻止”第一个做的事情:

secondForm.ShowDialog(firstForm);

但我不知道如何让 firstForm 阻止所有应用程序以防止用户使用它的已弃用版本。

我尝试了几种方法,比如获取当前进程 ID(或尝试获取)并将其转换为 IWin32Window。但似乎没有任何效果。

如果你需要它,我在这里添加我正在使用的代码:

 FormAsk  formAsk = new FormAsk (param1, param2);
 formAsk.StartPosition = FormStartPosition.CenterParent;
 formAsk.TopLevel = true;
 formAsk.TopMost = true;
 formAsk.DialogResult = formAsk .ShowDialog();
 if(formAsk.DialogResult.Equals(DialogResult.OK))
 {
      // do stuff
 }
 else
 {
      // do other stuff
 }

我也看到很多解决方案实现:

myForm.ShowDialog(this);

但是因为类型不兼容,VS开始哭了。我使用的是 MVVM 模式,所以我不能只将表单设置为所有者,因为我没有主表单。只需在 .xaml 中查看并在 c# 中查看控制器。

编辑:我想补充一些我在遇到这个问题后学到的评论,这可能有助于更好地理解我的情况。

程序的主要方法执行如下:

[STAThread]
    static void Main()
    {
        //stuff
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            try
            {
                //stuff
                STAApplicationContext context = new STAApplicationContext();
                Application.Run(context);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, Localization.Strings.error_popup_title);
                Application.Exit();
            }
        }
    }

而这个上下文是生成应用程序的服务层和视图管理器的上下文。如果我在服务层显示表单,showDialog() 方法不能“阻止”视图中的输入,但如果我从视图(由视图管理器生成和处理)中显示它们,我可以。视图和服务之间存在通信,因为在视图中触发的操作会调用服务方法,但在这种情况下,我想要的通信是相反的:服务调用视图控制器中的方法以通过 showDialog( ).

在你的第一个表格中做你的东西,然后你按下任何按钮来创建你的第二个表格,就像这样。 (伪代码)

button1_click()
{
   Form2 = new Form() 
   Form2.Owner = this;
}

现在您可以从您的 Form2 与您的所有者交谈,例如 this.Owner.Visible = false。

如果这就是您所要求的,这就是您创建所有者的方式。

您需要传递 IWin32Window interface to the ShowDialog 方法的一个实例。

IntPtr myWindowHandle = IntPtr(parent.Handle);
IWin32Window w = Control.FromHandle(myWindowHandle);

感谢那些试图帮助您回复的人。但是,尽管您的答案可能适用于其他情况,但我的答案有点不同。

终于解决了,我需要在更高的抽象层次上处理Forms。管理的信息是从异步任务中检索的,所以我不能在那里使用 showDialog 方法并阻止应用程序的 MainWindow。相反,我做了几个线程,等待它们并最终在我需要时显示对话框。这不是最好的方法,但考虑到上下文是我唯一能做的。