Piszę moją pierwszą aplikację w WPF i chcę, aby użytkownik wprowadził pewne dane w modalnym oknie dialogowym. Najwyraźniej nie jest to łatwe do wykonania w WPF, ponieważ okno nadrzędne pozostaje w pełni włączone, a metoda, która utworzyła nowe okno podrzędne, nie zatrzymuje się i nie czeka na wywołanie funkcji Close () przez okno podrzędne. Zamiast tego po prostu idzie do przodu. Nie tego chcę.
Jak sprawić, aby okno podrzędne było otwierane i aby okno nadrzędne oczekiwało na zamknięcie okna podrzędnego, zanim okno nadrzędne będzie kontynuowane?
.net
wpf
dialog
modal-dialog
Alex Baranosky
źródło
źródło
Odpowiedzi:
Czy próbowałeś pokazać swoje okno za pomocą metody ShowDialog ?
Nie zapomnij ustawić właściwości Owner w oknie dialogowym na okno główne. Pozwoli to uniknąć dziwnego zachowania, gdy Alt + Tab, itp.
źródło
Wiele z tych odpowiedzi jest uproszczonych, a jeśli ktoś zaczyna WPF, może nie znać wszystkich „wejść i wyjść”, ponieważ jest to bardziej skomplikowane niż zwykłe powiedzenie komuś „Użyj
.ShowDialog()
!”. Ale to jest metoda (nie.Show()
), której chcesz użyć, aby zablokować użycie okna bazowego i aby kod nie był kontynuowany, dopóki okno modalne nie zostanie zamknięte.Najpierw potrzebujesz 2 okien WPF. (Jeden będzie dzwonił do drugiego.)
Załóżmy, że z pierwszego okna, które nazywało się MainWindow.xaml, w jego kodzie za nim będzie:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } }
Następnie dodaj przycisk do kodu XAML:
<Button Name="btnOpenModal" Click="btnOpenModal_Click" Content="Open Modal" />
Kliknij
Click
procedurę prawym przyciskiem myszy i wybierz opcję „Przejdź do definicji”. Stworzy go dla Ciebie w MainWindow.xaml.cs:private void btnOpenModal_Click(object sender, RoutedEventArgs e) { }
W ramach tej funkcji musisz określić drugą stronę za pomocą jej klasy strony. Powiedzmy, że nazwałeś tę drugą stronę „ModalWindow”, tak aby stała się ona klasą strony i tak można ją utworzyć (wywołać):
private void btnOpenModal_Click(object sender, RoutedEventArgs e) { ModalWindow modalWindow = new ModalWindow(); modalWindow.ShowDialog(); }
Załóżmy, że masz wartość, którą chcesz ustawić w oknie modalnym. Utwórz pole tekstowe i przycisk w
ModalWindow
XAML:<StackPanel Orientation="Horizontal"> <TextBox Name="txtSomeBox" /> <Button Name="btnSaveData" Click="btnSaveData_Click" Content="Save" /> </StackPanel>
Następnie ponownie utwórz procedurę obsługi zdarzenia (inne
Click
zdarzenie) i użyj jej do zapisania wartości pola tekstowego w publicznej zmiennej statycznejModalWindow
i wywołajthis.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(); } }
Następnie po złożeniu
.ShowDialog()
oświadczenia możesz pobrać tę wartość i użyć jej:private void btnOpenModal_Click(object sender, RoutedEventArgs e) { ModalWindow modalWindow = new ModalWindow(); modalWindow.ShowDialog(); string valueFromModalTextBox = ModalWindow.myValue; }
źródło
Window.Show Window pokaże okno i będzie kontynuować wykonywanie - jest to wywołanie nieblokujące.
Window.ShowDialog zablokuje wątek wywołujący (w pewnym sensie [1]) i wyświetli okno dialogowe. Blokuje również interakcję z oknem nadrzędnym / właścicielem. Gdy okno dialogowe zostanie zamknięte (z dowolnego powodu) ShowDialog powróci do dzwoniącego i umożliwi dostęp do DialogResult (jeśli chcesz).
[1] Będzie utrzymywać pompowanie przez dyspozytora poprzez wpychanie ramki dyspozytora na dipatcher WPF. Spowoduje to, że komunikat pompa będzie dalej pompować.
źródło
Mając obiekt Window myWindow, myWindow.Show () otworzy go w sposób modelowy, a myWindow.ShowDialog () otworzy go modalnie. Jednak nawet ta ostatnia nie blokuje, z tego co pamiętam.
źródło
ShowDialog
nie wraca, dopóki modal nie zostanie zamknięty, więc blokuje aktualnie wykonywaną operację wysyłającą. AleShowDialog
sam skutecznie wywołujeDispatcher.Run()
, więc dyspozytor kontynuuje wykonywanie operacji, w efekcie utrzymując responsywność interfejsu użytkownika.