Dataniedziela, 9 sierpnia 2026 Czas07:47:19
← Aplikacje desktopowe (WPF)

Lekcja 11. Menu, paski narzędzi i menu kontekstowe

Średni

Po co się tego uczymy?

System menu to jeden z elementów wymienionych wprost w podstawie programowej (INF.04.5.3). Prawie każda aplikacja desktopowa ma pasek menu na górze (Plik, Edycja, Widok...), często też pasek narzędzi z ikonami i menu kontekstowe pod prawym przyciskiem myszy — te trzy elementy razem tworzą profesjonalnie wyglądający, wygodny w obsłudze interfejs.

Teoria

Menu (<Menu>) to klasyczny pasek menu znany z niemal każdego programu — składa się z pozycji głównych (MenuItem), z których każda może mieć rozwijaną listę podpozycji, kolejnych zagnieżdżonych podmenu, separatory (Separator) oddzielające grupy opcji, a nawet skróty klawiszowe wyświetlane obok nazwy (InputGestureText="Ctrl+S") — choć samo wyświetlenie tekstu skrótu to co innego niż jego faktyczne działanie (to trzeba obsłużyć osobno przez tzw. KeyBinding).

ToolBar (pasek narzędzi) to poziomy pasek z przyciskami — zwykle z samymi ikonami zamiast tekstu, dla szybkiego dostępu do najczęściej używanych funkcji (Nowy, Zapisz, Drukuj). Kontener ToolBarTray pozwala zgrupować kilka pasków narzędzi i przeciągać je w różne miejsca okna.

ContextMenu (menu kontekstowe) pojawia się po kliknięciu prawym przyciskiem myszy na dany element — przypisuje się je do właściwości ContextMenu dowolnej kontrolki. Typowy przykład: kliknięcie prawym przyciskiem na element listy pokazuje opcje "Edytuj", "Usuń", "Kopiuj".

Wszystkie trzy działają na tej samej zasadzie co przyciski z wcześniejszej lekcji — każda pozycja menu/przycisk na pasku ma atrybut Click="NazwaMetody" podpięty do metody w code-behind.

Przykład z życia

Otwórz dowolny edytor tekstu na komputerze: pasek menu na górze (Plik, Edycja, Widok, Pomoc), pod nim pasek narzędzi z ikonami (Nowy, Otwórz, Zapisz, Drukuj), a kliknięcie prawym przyciskiem myszy na zaznaczonym tekście pokazuje menu kontekstowe z opcjami Kopiuj/Wklej/Wytnij. To dokładnie te trzy elementy z tej lekcji, użyte razem w jednej, znajomej aplikacji.

Kod (XAML)

<Window x:Class="MenuApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Edytor" Height="350" Width="500">
    <DockPanel>
        <!-- Pasek menu -->
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Plik">
                <MenuItem Header="_Nowy" Click="Nowy_Click" InputGestureText="Ctrl+N"/>
                <MenuItem Header="_Zapisz" Click="Zapisz_Click" InputGestureText="Ctrl+S"/>
                <Separator/>
                <MenuItem Header="Za_mknij" Click="Zamknij_Click"/>
            </MenuItem>
            <MenuItem Header="_Edycja">
                <MenuItem Header="_Kopiuj" Click="Kopiuj_Click"/>
                <MenuItem Header="_Wklej" Click="Wklej_Click"/>
            </MenuItem>
        </Menu>

        <!-- Pasek narzedzi -->
        <ToolBar DockPanel.Dock="Top">
            <Button Content="Nowy" Click="Nowy_Click"/>
            <Button Content="Zapisz" Click="Zapisz_Click"/>
            <Separator/>
            <Button Content="Kopiuj" Click="Kopiuj_Click"/>
        </ToolBar>

        <!-- Obszar roboczy z menu kontekstowym pod prawym przyciskiem -->
        <TextBox x:Name="ObszarTekstu" AcceptsReturn="True" TextWrapping="Wrap">
            <TextBox.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Kopiuj" Click="Kopiuj_Click"/>
                    <MenuItem Header="Wklej" Click="Wklej_Click"/>
                    <MenuItem Header="Wyczysc" Click="Wyczysc_Click"/>
                </ContextMenu>
            </TextBox.ContextMenu>
        </TextBox>
    </DockPanel>
</Window>

Komentarz i wyjaśnienie kodu

Zwróć uwagę, że przyciski "Nowy", "Zapisz" i "Kopiuj" na pasku narzędzi (ToolBar) wywołują TE SAME metody (Nowy_Click, Zapisz_Click, Kopiuj_Click), co odpowiadające im pozycje w menu — to typowa, dobra praktyka: użytkownik może wykonać tę samą akcję na kilka sposobów (menu, pasek narzędzi, menu kontekstowe, czasem też skrót klawiszowy), a cała logika jest napisana raz, w jednym miejscu.

Podkreślenie przed literą w Header="_Plik" oznacza skrót klawiszowy Alt — naciśnięcie Alt+P otworzy to menu, litera "P" zostanie podkreślona wizualnie w interfejsie.

ContextMenu przypisany do TextBox.ContextMenu sprawia, że kliknięcie prawym przyciskiem myszy WEWNĄTRZ tego konkretnego pola tekstowego pokaże zdefiniowane tam opcje — inne kontrolki w oknie miałyby swoje własne (albo żadne) menu kontekstowe.

Ćwiczenie samodzielne

Utwórz projekt z powyższym XAML, dopisz puste metody obsługi (Nowy_Click, Zapisz_Click itd. — na razie wystarczy, że każda np. zmieni tytuł okna), uruchom i sprawdź, że menu, pasek narzędzi i menu kontekstowe wszystkie działają.

Zadania do pracy własnej

  1. Dodaj do menu "Plik" nową pozycję "Zapisz jako..." z separatorem oddzielającym ją od reszty opcji.

  2. Dodaj menu "Widok" z dwiema pozycjami typu przełącznik (MenuItem IsCheckable="True") — "Pokaż pasek narzędzi" i "Pokaż pasek statusu" — które chowają/pokazują odpowiednie elementy interfejsu przez zmianę ich Visibility.

  3. Zbuduj prosty "eksplorator plików" z ListBox reprezentującym listę plików, gdzie kliknięcie prawym przyciskiem myszy na elemencie listy pokazuje menu kontekstowe z opcjami "Otwórz", "Zmień nazwę", "Usuń" — każda opcja powinna wypisywać w pasku statusu, którego pliku dotyczyła akcja (na podstawie zaznaczonego elementu).

Typowe błędy

Duplikowanie kodu zamiast wspólnej metody — jeśli przycisk na pasku narzędzi i pozycja menu robią to samo, powinny wywoływać JEDNĄ, wspólną metodę, a nie dwie kopie tego samego kodu (trudniej wtedy o pomyłkę przy późniejszej zmianie logiki).

Zbyt głębokie zagnieżdżanie podmenu — więcej niż 2-3 poziomy zagnieżdżenia menu utrudniają użytkownikowi znalezienie potrzebnej opcji.

Brak menu kontekstowego tam, gdzie użytkownik go oczekuje — np. w polu tekstowym bez własnego ContextMenu, WPF i tak pokaże domyślne menu systemowe (Kopiuj/Wklej), ale w innych kontrolkach (np. na elemencie listy) brak menu kontekstowego może być mylące.

Nawiązanie do egzaminu zawodowego

To realizacja fragmentu INF.04.5.3 dotyczącego "systemu menu" i okien aplikacji. Razem z lekcjami o kontrolkach i dialogach kompletuje to zestaw podstawowych elementów interfejsu wymaganych na egzaminie.