Lekcja 10. Okna i dialogi — modalne, niemodalne i MessageBox
ŚredniPo co się tego uczymy?
Prawdziwe aplikacje rzadko mają tylko jedno okno — potrzebne są okna dialogowe do potwierdzeń, ustawień, formularzy szczegółów. Podstawa programowa (INF.04.5.3) wymaga wprost umiejętności pracy z oknem/dialogiem modalnym i niemodalnym — ta lekcja pokazuje, kiedy i jak ich używać.
Teoria
Okno modalne (ang. modal) blokuje interakcję z resztą aplikacji, dopóki nie zostanie zamknięte — użytkownik MUSI je obsłużyć (np. kliknąć OK/Anuluj), zanim wróci do głównego okna. Otwiera się metodą ShowDialog(). Typowe zastosowanie: okno "Zapisz zmiany przed zamknięciem?", formularz edycji szczegółów rekordu.
Okno niemodalne (ang. modeless/non-modal) pozwala dalej korzystać z głównego okna, mimo że dodatkowe okno jest otwarte — oba działają niezależnie. Otwiera się metodą Show(). Typowe zastosowanie: panel narzędzi, podgląd na żywo, okno pomocy, które chcemy mieć otwarte obok głównej pracy.
MessageBox to gotowa, wbudowana klasa do szybkich, prostych komunikatów (informacja, ostrzeżenie, pytanie tak/nie) — nie trzeba projektować własnego okna. Wywołuje się statyczną metodą MessageBox.Show(tekst, tytul, przyciski, ikona), a wynik (który przycisk kliknął użytkownik) sprawdza się przez porównanie z wartościami MessageBoxResult (np. MessageBoxResult.Yes).
Żeby przekazać dane MIĘDZY oknami (np. wynik formularza z okna dialogowego z powrotem do okna głównego), tworzy się w drugim oknie publiczną właściwość, ustawia się ją przed zamknięciem okna, a w oknie głównym odczytuje się ją PO wywołaniu ShowDialog() (bo dopiero wtedy program "czeka", aż użytkownik zamknie okno modalne).
Schemat
Okno modalne (ShowDialog) vs niemodalne (Show):
MODALNE: NIEMODALNE:
Okno glowne Okno dialogowe Okno glowne Okno pomocnicze
[zablokowane] <--- aktywne [aktywne] [tez aktywne]
| | |
| czeka... moga dzialac jednoczesnie,
| przelaczanie miedzy nimi
v (dopiero po zamknieciu) swobodne
[znow aktywne]
Przykład z życia
Kiedy w edytorze tekstu próbujesz zamknąć dokument z niezapisanymi zmianami, pojawia się okno modalne "Czy zapisać zmiany?" — nie możesz kliknąć nic innego w aplikacji, dopóki nie odpowiesz. Z kolei panel "Znajdź i zamień" w wielu edytorach jest oknem niemodalnym — możesz przełączać się między nim a dokumentem, przewijać tekst, i wracać do wyszukiwania bez zamykania panelu.
Kod (C#)
// MainWindow.xaml.cs - otwieranie okna dialogowego i odczyt wyniku
using System.Windows;
namespace OknaApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void PrzyciskEdytuj_Click(object sender, RoutedEventArgs e)
{
OknoEdycji okno = new OknoEdycji();
okno.ImieDoEdycji = EtykietaImie.Text; // przekazanie danych DO okna
bool? wynik = okno.ShowDialog(); // program CZEKA tutaj, az uzytkownik zamknie okno
if (wynik == true) // uzytkownik kliknal "Zapisz" w oknie dialogowym
{
EtykietaImie.Text = okno.ImieDoEdycji; // odczyt danych PO zamknieciu
}
}
private void PrzyciskUsun_Click(object sender, RoutedEventArgs e)
{
MessageBoxResult wynik = MessageBox.Show(
"Czy na pewno chcesz usunac ten rekord?",
"Potwierdzenie",
MessageBoxButton.YesNo,
MessageBoxImage.Warning
);
if (wynik == MessageBoxResult.Yes)
{
EtykietaImie.Text = "(usunieto)";
}
}
private void PrzyciskPomoc_Click(object sender, RoutedEventArgs e)
{
OknoPomocy okno = new OknoPomocy();
okno.Show(); // niemodalne - mozna dalej korzystac z okna glownego
}
}
}
Komentarz i wyjaśnienie kodu
PrzyciskEdytuj_Click tworzy nowe okno (OknoEdycji), ustawia jego publiczną właściwość ImieDoEdycji jeszcze przed pokazaniem, a potem wywołuje ShowDialog() — ta metoda ZWRACA WARTOŚĆ dopiero, gdy okno zostanie zamknięte, więc kod poniżej (odczyt okno.ImieDoEdycji) wykona się dopiero po zamknięciu. Sprawdzenie wynik == true pozwala rozróżnić, czy użytkownik kliknął "Zapisz" (ustawia w oknie dialogowym DialogResult = true) czy "Anuluj".
PrzyciskUsun_Click pokazuje typowe użycie MessageBox do potwierdzenia niebezpiecznej akcji — MessageBoxButton.YesNo pokazuje dwa przyciski, a wynik porównuje się z MessageBoxResult.Yes, żeby wykonać usunięcie tylko po potwierdzeniu.
PrzyciskPomoc_Click pokazuje okno NIEMODALNE przez Show() — program NIE czeka, wykonanie leci dalej natychmiast, a użytkownik może swobodnie przełączać się między oknem głównym a oknem pomocy.
Ćwiczenie samodzielne
Utwórz drugie okno w projekcie (Dodaj → Okno... w Visual Studio), dodaj mu publiczną właściwość typu string, i otwórz je jako modalne z głównego okna, przekazując i odczytując wartość dokładnie jak w przykładzie.
Zadania do pracy własnej
Dodaj przycisk "O programie", który pokazuje
MessageBoxz nazwą aplikacji, wersją i Twoim imieniem jako autora (tylko przycisk OK, ikona informacyjna).Zbuduj okno modalne "Dodaj produkt" z polami Nazwa i Cena, przyciskami Zapisz/Anuluj (Zapisz ustawia
DialogResult = truei zamyka okno, Anuluj ustawiafalse), i wyświetl dodany produkt na liście w oknie głównym po zamknięciu dialogu z wynikiem pozytywnym.Zbuduj aplikację z oknem głównym (lista zadań) i oknem niemodalnym "Statystyki" pokazującym na bieżąco liczbę zadań — okno statystyk powinno się automatycznie odświeżać (np. przez zdarzenie albo prosty timer) za każdym razem, gdy w oknie głównym dodasz lub usuniesz zadanie, mimo że oba okna są otwarte jednocześnie.
Typowe błędy
Użycie Show() tam, gdzie potrzebne jest ShowDialog() (i odwrotnie) — jeśli otworzysz okno przez Show() i od razu spróbujesz odczytać dane, które użytkownik dopiero wpisze, dostaniesz puste/nieaktualne wartości, bo program nie zaczekał na zamknięcie okna.
Otwieranie tego samego okna modalnego wielokrotnie bez sprawdzenia stanu — może prowadzić do wielu identycznych okien nałożonych na siebie, jeśli nie ma odpowiedniego zabezpieczenia.
Zapominanie o ustawieniu DialogResult w oknie dialogowym — bez tego ShowDialog() zwróci null zamiast jednoznacznego true/false, co utrudnia sprawdzenie, czy użytkownik zaakceptował, czy anulował.
Nawiązanie do egzaminu zawodowego
To realizacja INF.04.5.3 — "okno/dialog modalny/niemodalny/kontrolki... okna dialogowe". Znajomość różnicy między Show() a ShowDialog() to jedno z najczęściej sprawdzanych zagadnień w zadaniach egzaminacyjnych z aplikacją wieloOkienkową.