2009-01-31 5 views
104

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

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

ответ

187

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

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

+2

Я учусь, хе-хе ... Очень приятно, спасибо –

+74

Не забудьте установить свойство Owner в диалоговом окне. В противном случае пользователь получит странное поведение, когда Alt + Tabbing и т. Д. –

+3

@EdwardBrey серьезно BIG PET PEEVE –

2

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

+6

Я считаю, что он блокирует. Код после myWindow.Show() не выполняется до тех пор, пока myWindow не вызовет Close(). –

24

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

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

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

+0

объясните это более подробно пожалуйста? Я рассматриваю аналогичную проблему, когда у меня есть тестовый процесс, но предупреждения могут появляться как модальные диалоги, но я не хочу блокировать выполнение. – Firoso

13

Многие из этих ответов упрощены, и если кто-то начинает 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) 
{ 
} 

В пределах этой функции, вы должны указать другую страницу, используя свою страницу класс. Допустим, вы назвали, что другая страница «модальное окно», так что становится его страницы класс и как вы бы создать экземпляр (вызов) это:

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; 
} 
+1

Это не работает. Ваша ModalPage должна расширять 'Window', а не' Page'. –

+0

У меня это было в коде. Ты прав. Я обновил свой ответ. В основном я пытался предоставить сатинизированную версию фактического кода моего проекта, поэтому я знаю, что эта «фреймворк» работает, но да, я должен был иметь «Окно», а не «Страница». Наверное, утром не было моего кофе. – vapcguy

+1

Теперь все в порядке. Простой и функциональный пример. Благодарю. –

Смежные вопросы