简体   繁体   English

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

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

I have a Windows Desktop App with an auto-update method implemented.我有一个 Windows 桌面应用程序,它实现了自动更新方法。 I want to show a custom Form (because I need to change the button texts) asking the user if he or she wants to download the new version or not when a new update is detected and I want to "block" all input actions in the Desktop App until the user has made his selection.我想显示一个自定义表单(因为我需要更改按钮文本),在检测到新更新时询问用户是否要下载新版本并且我想“阻止”中的所有输入操作桌面应用程序,直到用户做出选择。

After reading Form.ShowDialog() documentation and several topics here saying "ShowDialog() is not making my windows modal" and several answers replying "You need to properly set the owner" I still don't understand how to set this owner.在阅读了 Form.ShowDialog() 文档和此处的几个主题后说“ShowDialog() 没有使我的 windows 模态”和几个回复“您需要正确设置所有者”的答案后,我仍然不明白如何设置此所有者。 Of course if I make two forms and the first one shows the second, I can "block" the first one doing:当然,如果我制作两个 forms 并且第一个显示第二个,我可以“阻止”第一个这样做:

secondForm.ShowDialog(firstForm);

But I don't know how to make that the firstForm blocks all the application to prevent the user using a deprecated version of it.但我不知道如何使 firstForm 阻止所有应用程序以防止用户使用它的弃用版本。

I tried several approaches like getting the current id process (or trying to get it) and convert it to IWin32Window.我尝试了几种方法,例如获取当前 id 进程(或尝试获取它)并将其转换为 IWin32Window。 But nothing seemed to work.但似乎没有任何效果。

If you need it, I add here the code I'm using:如果你需要它,我在这里添加我正在使用的代码:

 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
 }

I've also seen lots of solution implementing:我还看到很多解决方案实施:

myForm.ShowDialog(this);

But VS start's crying because the types are not compatible.但是因为类型不兼容,VS 开始哭了。 I'm using a MVVM pattern so I can't just set a Form as an owner because I don't have a main form.我使用的是 MVVM 模式,所以我不能只将表单设置为所有者,因为我没有主表单。 Just views in.xaml and views controllers in c#.只需查看 in.xaml 并查看 c# 中的控制器。

Edit: I would like to add few comments I learned after facing this issue that may help to understand better my situation.编辑:我想补充一些我在面对这个问题后学到的评论,这可能有助于更好地理解我的情况。

The main method of the program executes the following:程序的主要方法执行如下:

[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();
            }
        }
    }

And this context is the one that generates the service layer and views manager of the application.这个上下文是生成应用程序的服务层和视图管理器的上下文。 If I display the Forms in the service layer, showDialog() method can not "block" the input in the views but if I display them from the views (generated and handled by the view manager) i can.如果我在服务层显示 Forms,showDialog() 方法不能“阻止”视图中的输入,但如果我从视图(由视图管理器生成和处理)中显示它们,我可以。 There's a communication between views and service, because actions triggered in the views have as consequence a service method call, but in this case the communication I want is the opposite: the service calling the methods in the view controllers to display the Forms by showDialog().视图和服务之间存在通信,因为在视图中触发的操作会导致服务方法调用,但在这种情况下,我想要的通信是相反的:服务调用视图控制器中的方法以显示 Forms by showDialog( ).

You need to pass an instance of the IWin32Window interface to the ShowDialog method.您需要将IWin32Window接口的实例传递给ShowDialog方法。

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

Do your Stuff in your first Form and whatever button you press to create your second Form just go like this.在你的第一个表格中做你的东西,然后按任何按钮来创建你的第二个表格,就像这样 go。 (Pseudo Code) (伪代码)

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

and now from your Form2 you can talk to your Owner with this.Owner.Visible = false for example.现在从您的 Form2 中,您可以使用 this.Owner.Visible = false 与您的所有者交谈。

Thats how you make the Owner if thats what you asked for.如果那是您的要求,那就是您成为所有者的方式。

Thanks those who tried to help with your replies.感谢那些试图帮助您回复的人。 However, although your answers probably will work in other circumstances, mine where a bit different.但是,尽管您的答案可能适用于其他情况,但我的情况有所不同。

Finally I achieved to solve it, I needed to do the handle with Forms in a higher level of abstraction.最后我实现了解决它,我需要在更高的抽象层次上处理 Forms 的句柄。 The information managed was retrieved from an asynchronous task so I couldn't use there a showDialog method and block the MainWindow of the application.管理的信息是从异步任务中检索的,所以我不能在那里使用 showDialog 方法并阻止应用程序的 MainWindow。 Instead I did several threads, wait them and eventually show dialogs when I needed.相反,我做了几个线程,等待它们并最终在我需要时显示对话框。 It's not the best approach, but given the context is the only thing I could do.这不是最好的方法,但考虑到上下文是我唯一能做的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM