Как создать модальный диалог в WPF?
-
20-08-2019 - |
Вопрос
Я пишу свое первое приложение в WPF и хочу, чтобы пользователь вводил некоторые данные в модальном диалоговом окне.По-видимому, это непросто сделать в WPF, потому что родительское окно остается полностью включенным, а метод, создавший новое дочернее окно, не останавливается и не ожидает вызова Close() дочерним окном.Вместо этого он просто продолжает двигаться вперед.Это не то, чего я хочу.
Как я могу заставить дочернее окно открыться, а родительское окно дождаться закрытия дочернего окна, прежде чем родительское окно продолжит выполнение?
Решение
Вы пробовали показывать свое окно с помощью Показать каталог способ?
Не забудьте установить Собственность владельца из диалогового окна перейдите в главное окно.Это позволит избежать странного поведения при нажатии Alt + Tabbing и т.д.
Другие советы
Многие из этих ответов упрощены, и если кто-то начинает 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)
{
}
В рамках этой функции вы должны указать другую страницу, используя ее класс page.Допустим, вы назвали эту другую страницу "ModalWindow", так что это становится ее классом page и именно так вы бы создавали (вызывали) ее экземпляр:
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;
}
Window.Show Window покажет окно и продолжит выполнение - это неблокирующий вызов.
Окно.ShowDialog заблокирует вызывающий поток (своего рода [1]) и покажет диалоговое окно.Это также заблокирует взаимодействие с родительским окном / окном владельца.Когда диалоговое окно будет закрыто (по какой-либо причине), ShowDialog вернется к вызывающему и позволит вам получить доступ к DialogResult (если вы этого хотите).
[1] Это будет поддерживать загрузку диспетчера, помещая фрейм диспетчера в дипатчер WPF.Это приведет к тому, что насос сообщений продолжит перекачку.
Если задан объект Window MyWindow, MyWindow.Show() откроет его модально, а MyWindow.ShowDialog() откроет его модально.Однако, насколько я помню, даже последнее не блокирует.