Как сделать модальный диалог в WPF?

Я пишу свое первое приложение в WPF и хочу, чтобы пользователь вводил некоторые данные в модальное диалоговое окно. По-видимому, это непросто сделать в WPF, потому что родительское окно остается полностью включенным, а метод, создавший новое дочернее окно, не останавливается и ждет, пока дочернее окно вызовет Close(). Вместо этого он просто продолжает двигаться вперед. Это не то, что я хочу.

Как я могу открыть дочернее окно и запустить родительское окно для закрытия дочернего элемента до того, как родительское окно продолжит выполнение?

Ответ 1

Пробовал ли вы показывать свое окно с помощью метода ShowDialog?

Не забудьте установить свойство владельца в диалоговом окне в главное окно. Это позволит избежать странного поведения, когда Alt + Tabbing и т.д.

Ответ 2

Окно Window.Show отобразит окно и продолжит выполнение - это неблокирующий вызов.

Window.ShowDialog заблокирует вызывающий поток (kinda [1]) и покажет диалог. Он также блокирует взаимодействие с родительским/владеющим окном. Когда диалог отклоняется (по какой бы то ни было причине) ShowDialog вернется к вызывающему абоненту и позволит вам получить доступ к DialogResult (если вы этого захотите).

[1] Он будет поддерживать откачку диспетчера, нажимая рамку диспетчера на dipatcher WPF. Это заставит насос сообщений продолжать накачку.

Ответ 3

Многие из этих ответов упрощены, и если кто-то начинает WPF, они могут не знать всех "ins-and-outs", поскольку это сложнее, чем просто говорить кому-то "Use .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;
}

Ответ 4

Учитывая объект Window myWindow, myWindow.Show() откроет его modessly, а myWindow.ShowDialog() откроет его модально. Однако даже последний не блокирует, из того, что я помню.