如何在WPF中进行模式对话框?


133

我正在WPF中编写我的第一个应用程序,希望用户在模态对话框窗口中输入一些数据。显然,在WPF中这样做并不简单,因为父窗口保持完全启用状态,并且创建新子窗口的方法不会停止并等待子窗口调用Close()。相反,它一直在前进。这不是我想要的。

我如何才能打开子窗口,并让父窗口在继续执行父窗口之前等待子窗口关闭?


在此处分享我的答案,因为它可能会帮助某人从Google那里徘徊。
Shahin Dohan

Answers:



43

这些答案很多都是简单的,如果有人开始使用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();
}

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

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

然后Click再次创建一个事件处理程序(另一个事件),并使用它将文本框值保存到on 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;
}

29

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

Window.ShowDialog将阻止调用线程(类型[1]),并显示对话框。它还将阻止与父/所有者窗口的交互。取消对话框时(无论出于何种原因),ShowDialog将返回到调用方,并允许您访问DialogResult(如果需要)。

[1]通过将调度器框架推到WPF分配器上,可以保持调度器处于抽水状态。这将导致消息泵继续泵送。


请详细解释一下吗?我正在看一个类似的问题,我正在运行一个测试过程,但是警告消息可以作为模式对话框弹出,但我不想阻止执行。
费罗索(Firoso)

2

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


6
我相信它会阻止。myWindow.Show()之后的代码要等到myWindow调用Close()之后才能执行。
Alex Baranosky

您和@AlexBaranosky都是正确的:ShowDialog在关闭模式之前不会返回,因此它会阻止当前正在执行的调度程序操作。但是ShowDialog它本身有效地调用Dispatcher.Run(),因此调度程序继续执行操作,实际上使UI保持响应。
马特·托马斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.