Aplikacje desktopowe · Menu
Menu, paski narzędzi i menu kontekstowe
Prawie każdy program ma pasek menu, pasek narzędzi z przyciskami i menu pod prawym przyciskiem myszy. Razem tworzą wygodny interfejs. Zbudujesz je tak, aby każda akcja była napisana raz i dostępna z kilku miejsc.
- około 40 minut
- WPF · Menu · ToolBar · ContextMenu
- INF.04.5.3
Po tej lekcji: zbudować Menu z podmenu i separatorem, ToolBar i ContextMenu, podpiąć je pod wspólne metody oraz wyjaśnić, czym są klawisze dostępu (_) i InputGestureText.
Zacznijmy od edytora
Trzy drogi do jednej akcji
Otwórz dowolny edytor tekstu. Na górze jest pasek menu (Plik, Edycja, Widok), pod nim pasek narzędzi z ikonami (Nowy, Zapisz, Kopiuj), a prawy przycisk myszy na tekście pokazuje menu kontekstowe. To właśnie te trzy elementy z podstawy programowej INF.04.5.3.
Wszystkie trzy działają tak samo jak zwykły przycisk: pozycja ma atrybut Click wskazujący metodę w code-behind. Dzięki temu „Zapisz” z menu, z paska i ze skrótu to jedna metoda.
1 · Poznaj narzędzia
Menu, ToolBar i ContextMenu
Menupasek na górze
Składa się z MenuItem, które mogą mieć podpozycje, Separator rozdzielający grupy i skróty (InputGestureText).
Na przykład Plik, Edycja, Widok
ToolBarszybkie przyciski
Poziomy pasek przycisków (zwykle z ikonami). Kilka pasków zgrupujesz w ToolBarTray i przeciągniesz w inne miejsca.
Na przykład Nowy, Zapisz, Drukuj
ContextMenuprawy przycisk
Pojawia się po kliknięciu prawym przyciskiem. Przypisujesz je do właściwości ContextMenu konkretnej kontrolki.
Na przykład Kopiuj, Wklej, Wyczyść
Laboratorium · ćwiczenie w przeglądarce, do którego odsyłają rozgrzewki na końcu lekcji
2 · Sprawdź w działaniu
Ta sama metoda, trzy miejsca
Kliknij „Zapisz” w menu Plik, potem „Zapisz” na pasku narzędzi. Kliknij prawym przyciskiem w polu tekstu i wybierz „Wyczyść”. Dziennik po prawej pokaże, która metoda się wykonała i skąd przyszło zdarzenie. Przełącz w menu Widok pasek narzędzi.
Użytkownik wybiera drogę, a Ty piszesz logikę raz. Pasek narzędzi i menu kontekstowe tylko wskazują te same metody.
3 · Wygląd
MainWindow.xaml
Całe okno to DockPanel: menu i pasek narzędzi przypięte do góry, pasek statusu do dołu, a pole tekstowe wypełnia resztę.
<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>
<MenuItem Header="_Widok">
<MenuItem x:Name="MenuPasekNarzedzi" Header="Pokaż pasek narzędzi"
IsCheckable="True" IsChecked="True" Click="Widok_Click" />
</MenuItem>
</Menu>
<!-- Pasek narzędzi -->
<ToolBar x:Name="PasekNarzedzi" DockPanel.Dock="Top">
<Button Content="Nowy" Click="Nowy_Click" />
<Button Content="Zapisz" Click="Zapisz_Click" />
<Separator />
<Button Content="Kopiuj" Click="Kopiuj_Click" />
</ToolBar>
<!-- Pasek statusu -->
<StatusBar DockPanel.Dock="Bottom">
<TextBlock x:Name="EtykietaStatus" Text="Gotowe" />
</StatusBar>
<!-- 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="Wyczyść" Click="Wyczysc_Click" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</DockPanel>
</Window>
Header="_Plik"Podkreślnik przed literą tworzy klawisz dostępu: Alt+P otwiera to menu.InputGestureText="Ctrl+S"Wyświetla skrót obok nazwy. To tylko napis. Prawdziwy skrót wymaga osobnej obsługi, np.KeyBinding.SeparatorLinia rozdzielająca grupy opcji, w menu i na pasku narzędzi.IsCheckable="True"Pozycja menu staje się przełącznikiem z ptaszkiem, a stan odczytasz zIsChecked.TextBox.ContextMenuMenu kontekstowe tylko tego pola tekstowego.
4 · Działanie
MainWindow.xaml.cs
Każda metoda obsługuje akcję bez wiedzy, skąd została wywołana. Dlatego tę samą metodę podpinasz pod menu, pasek i menu kontekstowe.
using System.Windows;
namespace MenuApp;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Nowy_Click(object sender, RoutedEventArgs e)
{
ObszarTekstu.Clear();
EtykietaStatus.Text = "Nowy dokument";
}
private void Zapisz_Click(object sender, RoutedEventArgs e)
{
EtykietaStatus.Text = "Zapisano dokument";
}
private void Zamknij_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void Kopiuj_Click(object sender, RoutedEventArgs e)
{
ObszarTekstu.Copy();
EtykietaStatus.Text = "Skopiowano zaznaczenie";
}
private void Wklej_Click(object sender, RoutedEventArgs e)
{
ObszarTekstu.Paste();
EtykietaStatus.Text = "Wklejono ze schowka";
}
private void Wyczysc_Click(object sender, RoutedEventArgs e)
{
ObszarTekstu.Clear();
EtykietaStatus.Text = "Wyczyszczono";
}
private void Widok_Click(object sender, RoutedEventArgs e)
{
PasekNarzedzi.Visibility = MenuPasekNarzedzi.IsChecked ? Visibility.Visible : Visibility.Collapsed;
}
}
Nowy_Click,Zapisz_Click,Kopiuj_ClickWspólne dla wszystkich trzech źródeł.ObszarTekstu.Copy()iPaste()Gotowe metodyTextBoxdo obsługi schowka.Widok_ClickCzytaIsCheckedz pozycji menu i ustawia widoczność paska narzędzi.MenuPasekNarzedzi.IsChecked ? Visible : CollapsedOperator warunkowy zamienia stan ptaszka na wartośćVisibility.
5 · Ściągawka
Elementy menu i ich odpowiedniki w WinForms
| WPF | Windows Forms | Co robi |
|---|---|---|
Menu + MenuItem | MenuStrip + ToolStripMenuItem | Pasek menu z pozycjami. |
Header | Text | Napis pozycji menu. Znak _ (WPF) lub & (Forms) tworzy klawisz dostępu. |
ToolBar | ToolStrip | Pasek narzędzi. |
ContextMenu | ContextMenuStrip | Menu pod prawym przyciskiem. |
IsCheckable, IsChecked | CheckOnClick, Checked | Pozycja menu jako przełącznik. |
StatusBar | StatusStrip | Pasek statusu u dołu okna. |
6 · Czego unikać
Trzy błędy w menu
Kopia kodu zamiast wspólnej metody
<MenuItem Header="Zapisz" Click="ZapiszMenu_Click" />
<Button Content="Zapisz" Click="ZapiszPasek_Click" />Dwie metody z tym samym kodem. Zmiana logiki wymaga poprawek w dwóch miejscach.
<MenuItem Header="Zapisz" Click="Zapisz_Click" />
<Button Content="Zapisz" Click="Zapisz_Click" />Jedna metoda obsługuje obie drogi, więc logika jest w jednym miejscu.
`InputGestureText` bez prawdziwego skrótu
<MenuItem Header="Zapisz" InputGestureText="Ctrl+S" Click="Zapisz_Click" />Napis „Ctrl+S” się wyświetla, ale naciśnięcie skrótu nic nie robi.
<!-- skrót trzeba osobno podpiąć, np. przez KeyBinding w Window.InputBindings -->InputGestureText tylko opisuje skrót. Działanie to osobna sprawa.
Zbyt głębokie podmenu
Plik → Eksport → Obrazy → Formaty → Rastrowe → PNGUżytkownik gubi się i nie znajduje opcji.
Plik → Eksportuj jako… (dalszy wybór formatu w oknie dialogowym)Dwa do trzech poziomów to rozsądny limit. Resztę przenieś do okna dialogowego.
7 · Sprawdź się
Menu, pasek czy menu kontekstowe?
Cztery sytuacje z interfejsem edytora.
Podsumowanie
Co warto zapamiętać
- Menu składa się z
MenuItem,Separatori skrótów. ToolBar to pasek przycisków. ContextMenu pojawia się pod prawym przyciskiem. _przed literą wHeadertworzy klawisz dostępu (Alt+litera).InputGestureTexttylko wyświetla skrót, jego działanie obsługujesz osobno.IsCheckableiIsCheckedzamieniają pozycję menu w przełącznik.- Wszystkie trzy elementy wskazują te same metody, więc logika jest napisana raz.
Dalej na swoim koncie
Rozgrzewki, quiz i zadania są w biurku ucznia.
Teoria jest otwarta dla wszystkich. Żeby rozwiązywać zadania, zapisywać szkice i widzieć swój postęp, zaloguj się.
Zaloguj się →