【问题标题】:How to make modal dialog in WPF?如何在 WPF 中制作模态对话框?
【发布时间】:2010-10-04 16:46:47
【问题描述】:

如果我有一个 Xaml 窗口,如何将它作为子窗口打开,然后让父窗口等待子窗口关闭,然后父窗口继续执行?

【问题讨论】:

  • 在此处分享 my answer,因为它可能会帮助从 Google 到这里徘徊的人。

标签: .net wpf dialog modal-dialog


【解决方案1】:

您是否尝试使用ShowDialog 方法显示您的窗口?

不要忘记将对话窗口上的Owner property 设置为主窗口。这将避免在 Alt+Tabbing 等时出现奇怪的行为。

【讨论】:

    【解决方案2】:

    其中很多答案都很简单,如果有人开始 WPF,他们可能不知道所有的“来龙去脉”,因为这比告诉别人“使用.ShowDialog()!”要复杂得多。但这是您想要使用的方法(不是.Show()),以阻止使用基础窗口并阻止代码继续运行,直到模态窗口关闭。

    首先,您需要 2 个 WPF 窗口。 (一个会打电话给另一个。)

    假设从第一个窗口开始,它被称为 MainWindow.xaml,在其代码隐藏中将是:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
    

    然后将您的按钮添加到您的 XAML:

    <Button Name="btnOpenModal" Click="btnOpenModal_Click" Content="Open Modal" />
    

    然后右键单击Click 例程,选择“转到定义”。它将在 MainWindow.xaml.cs 中为您创建它:

    private void btnOpenModal_Click(object sender, RoutedEventArgs e)
    {
    }
    

    在该函数中,您必须使用其页面类指定另一个页面。假设您将另一个页面命名为“ModalWindow”,这样就成为它的页面类,并且是您实例化(调用)它的方式:

    private void btnOpenModal_Click(object sender, RoutedEventArgs e)
    {
        ModalWindow modalWindow = new ModalWindow();
        modalWindow.ShowDialog();
    }
    

    假设您需要在模态对话框中设置一个值。在ModalWindow XAML 中创建一个文本框和一个按钮:

    <StackPanel Orientation="Horizontal">
        <TextBox Name="txtSomeBox" />
        <Button Name="btnSaveData" Click="btnSaveData_Click" Content="Save" /> 
    </StackPanel>
    

    然后再次创建一个事件处理程序(另一个Click 事件)并使用它将文本框值保存到ModalWindow 上的公共静态变量并调用this.Close()

    public partial class ModalWindow : Window
    {
        public static string myValue = String.Empty;        
        public ModalWindow()
        {
            InitializeComponent();
        }
    
        private void btnSaveData_Click(object sender, RoutedEventArgs e)
        {
            myValue = txtSomeBox.Text;
            this.Close();
        }
    }
    

    然后,在您的 .ShowDialog() 声明之后,您可以获取该值并使用它:

    private void btnOpenModal_Click(object sender, RoutedEventArgs e)
    {
        ModalWindow modalWindow = new ModalWindow();
        modalWindow.ShowDialog();
    
        string valueFromModalTextBox = ModalWindow.myValue;
    }
    

    【讨论】:

      【解决方案3】:

      Window.Show 将显示窗口,并继续执行——这是一个非阻塞调用。

      Window.ShowDialog 将阻塞调用线程(有点 [1]),并显示对话框。它还将阻止与父/拥有窗口的交互。当对话框被关闭时(无论出于何种原因),ShowDialog 将返回给调用者,并允许您访问 DialogResult(如果需要)。

      [1] 它将通过将调度程序框架推送到 WPF 调度程序上来保持调度程序的运行。这将导致消息泵继续泵送。

      【讨论】:

      • 请详细解释一下?我正在研究一个类似的问题,我正在运行一个测试进程,但警告消息可以作为模式对话框弹出,但我不想阻止执行。
      【解决方案4】:

      给定一个 Window 对象 myWindow,myWindow.Show() 将以非模式打开它,而 myWindow.ShowDialog() 将以模式打开它。但是,据我记得,即使是后者也不会阻止。

      【讨论】:

      • 我相信它会阻塞。 myWindow.Show() 之后的代码直到 myWindow 调用 Close() 之后才会执行。
      • 你和@AlexBaranosky 都是正确的:ShowDialog 在模式关闭之前不会返回,因此它会阻止当前执行的调度程序操作。但是ShowDialog 本身有效地调用了Dispatcher.Run(),因此调度程序继续执行操作,实际上保持 UI 响应。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多