Prikazy jsou ve WPF velmi vyhodne zvlaste v pripade, kdy potrebujete namapovat nejakou klavesovou zkratku pomoci KeyGesture(a k dispozici je i trida MouseGesture dedici taky od InputGesture, takze by slo mozna i nejak udelat gesto mysi, nicmene s timto jsem se jeste nikdy nesetkal, spise bych rekl ze to bude treba klik na leve tlacitko mysi + klaves na klavesnici) nebo pokud potrebujete automaticky povolovat / zakazovat nejake tlacitko nebo cokoliv co lze namapovat na prikaz – staci napsat metodu CanExecute tridy CommandBinding ktera pak se automaticky co cca 500ms vola a povoluje / zakazuje napr. tlacitko.
Takze jak si udelat jednoduchy prikaz?
Prvnim krokem je vytvoreni tridy jakehokoliv nazvu(ja vzdy pouzivam {nazev_programu}Commands. Do ni napiste vytvoreni instanci trid RoutedCommand, ktera si za svuj prvni parametr bere nazev(ktery jsem zatim ale nikdy nepouzil), pak nazev libovolne tridy ktera je ve jmennem prostoru ve kterem budete tento prikaz vyuzivat.
Toto byly 2 povinne parametry ale konstuktoru tridy jsou celkove 3. U me fungoval i konstruktor bez parametru a nebo konstruktor se 2mi zminovanymi parametry + 3. ktery specifikuje zkratky vstupnich zarizeni(klavesnice, mys).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using HostingManager; /// <summary> /// Tato trida je pouze proto aby se v ni deklarovali Commands, ktere pak budes pouzivat v XAMLu /// </summary> using System.Windows.Input; namespace HostingManager { public static class HostingManagerCommands { /// <summary> /// Prikaz, na ktery se budeme odkazovat vzdy v vlastnosti Command /// </summary> public static RoutedCommand RunThread = new RoutedCommand();//"commandRunThread", typeof(MainWindow), new InputGestureCollection(new KeyGesture[] { new KeyGesture(Key.S, ModifierKeys.Control) })); } } |
Pak si pridejte jmenny prostor nejlepe do root tagu ve vasem XAML souboru – v mem pripade to je Window a jmenny prostor jsem si nazval src. Myslim ze tento jmenny prostor byste tam uz meli mit, takze si to prvne jen zkontrolujte
1 |
xmlns:src="clr-namespace:HostingManager" |
Dalsim krokem je vytvorit obalujici element Window.CommandBindings hned za oteviracim tagem Window:
1 2 3 |
<Window.CommandBindings> <CommandBinding Command="src:HostingManagerCommands.RunThread" x:Name="cmdRunThread" CanExecute="cmdRunThread_CanExecute" Executed="cmdRunThread_Executed"> </CommandBinding> </Window.CommandBindings> |
Pak je potreba mit tlacitko ktere budeme automaticky povolovat nebo zakazovat a listbox, do nehoz budeme pocitat protoze budeme pouzivat vlakna:
1 2 3 4 5 6 |
<StackPanel Orientation="Vertical"> <Button x:Name="btnCancelUpload" Command="src:HostingManagerCommands.RunThread"> <Image Source="Run.png" Width="16" Height="16"> </Image> </Button> <ListBox x:Name="lbLog"> </ListBox> </StackPanel> |
Protoze budeme pouzivat vlakna, musite si definovat tridu, ktera obsahuje delegata odkazujici na metodu ktera pridava do ListBox objekty:
1 2 3 4 5 6 7 8 9 10 |
using System.Windows.Controls; public delegate void insertToListBoxWpf(ListBox lb, int index, object o); public partial class IHWPF { public static insertToListBoxWpf delegateInsertToListBoxWpf = new insertToListBoxWpf(insertToListBoxWpfValue); public static void insertToListBoxWpfValue(ListBox lb, int index, object o) { lb.Items.Insert(index, o); } } |
Nakonec uz jen napisete do code-behind tridy Window metody CanExecute, Executed, OnLoad a take vytvorime globalni promennou Thread, abysme mohli toto vlakno zapinat i kontrolovat zda je zive – vsechno v jine metode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Thread thread = null; public MainWindow() { this.Loaded += MainWindow_Loaded; } void MainWindow_Loaded(object sender, RoutedEventArgs e) { thread = new Thread(Run); thread.Start(); } void Run() { for (int i = 0; i < 5; i++) { Thread.Sleep(1000); Dispatcher.Invoke(IHWPF.delegateInsertToListBoxWpf, lbLog, 0, i.ToString()); } } private void cmdRunThread_Executed(object sender, ExecutedRoutedEventArgs e) { Dispatcher.Invoke(IHWPF.delegateInsertToListBoxWpf, lbLog, 0, "Vlakno bylo znovu spusteno"); thread = new Thread(Run); thread.Start(); } /// <summary> /// Az se vlakno dokonci, tato metoda znovu nastavi e.CanExecute na True /// </summary> /// <param name="sender"> /// <param name="e"> private void cmdRunThread_CanExecute(object sender, CanExecuteRoutedEventArgs e) { bool vr = true; if (thread != null) { vr = !thread.IsAlive; } e.CanExecute = vr; } |
Vysledek? Tlacitko neslo zmacknout dokud vlakno bezelo