Novinky ve WPF 4 - InputBinding
V jednom z minulých článků jsem se věnoval příkazům ve WPF a zmiňoval jsem se o zajímavé třídě nazvané InputBinding, která zajišťuje napojení klávesových zkratek a myši na odebírané příkazy.
Takže to vypadá, že samotný InputBinding tak úplně novinkou není. Jak však víte nebo jste po projití zdejších stránek mohli odtušit, vývoj ve WPF směřuje k tomu, že bude použit návrhový vzor Model-View-ViewModel, který hodně spolehá na kvalitní DataBinding. A tak je tedy potřeba mít co nejvíce elementů přizpůsobených k DataBindingu, což znamená, aby většina vlastností byla typu DependencyProperty.
A právě toto je novinka v přicházející verzi .NET 4.0 WPF u InputBindingu, kdy veškeré vlastnosti je nyní možné bindovat, nejčastěji tedy na napojený ViewModel a to jak u MouseGestures tak také pro KeyGestures.
Rád bych tedy ukázal, jak bylo dříve možné, nebo spíše díky omezení nemožné, napojit příkaz na některou klávesovou zkratku nebo gesto myši a jakým způsobem se to změnilo s verzí WPF 4.0. Pojďme se tedy podívat na ukázku, která využívá doplněný markup extension, bez kterého by napojení na příkaz nebylo možné:
<Window.InputBindings> <KeyBinding Command="{Binding MainCommand}" Key="t" Modifiers="Control" /> <MouseBinding Command="{Binding MainCommand}" MouseAction="RightClick" /> </Window.InputBindings> <Grid> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Button Grid.Row="0" Content="Click" Command="{Binding MainCommand}" /> <TextBlock Grid.Row="1" Text="{Binding MainText}" /> </Grid>
Jak vidno, vše bylo deklarativně uvedeno v XAMLu a vývojář neměl příliš možností jak toto ovlivnit, tedy ono to samozřejmě šlo obejít, ale znamenalo to vytvořit si další markup extensions a nebo používat DependencyObject.
A zde je ukázka toho, jak by mohla vypadat definici ve ViewModelu ve verzi wpf 4.0, kde zároveň doplníme hodnoty pro klávesové zkratky a také gesto myši.
public class MainViewModel: INotifyPropertyChanged { private Random _rnd; private string _mainText; private ICommand _mainCommand; public MainViewModel() { _rnd = new Random(); _mainCommand = new DelegateCommand(OnMainCommand); ((DelegateCommand)_mainCommand).Key = Key.T; ((DelegateCommand)_mainCommand).Modifiers = ModifierKeys.Control; ((DelegateCommand)_mainCommand).MouseAction = MouseAction.RightClick; } private void OnMainCommand() { string s = new string((char)_rnd.Next(65, 80), 1); MainText += s; } public string MainText { get { return _mainText; } set { _mainText = value; OnPropertyChanged("MainText"); } } public ICommand MainCommand { get { return _mainCommand; } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
Tento ViewModel využívá jednoduchou třídu DelegateCommand, která implementuje rozhraní ICommand a zároveň doplňuje tři vlastnosti pro možnost bindingu, kterými jsou Key, Modifiers a MouseAction.
Nyní už deklarativní část, kde vše napojíme a můžeme si tak novinku vyzkoušet v praxi.
<Window.InputBindings> <KeyBinding Command="{Binding MainCommand}" Key="{Binding MainCommand.Key}" Modifiers="{Binding MainCommand.Modifiers}" /> <MouseBinding Command="{Binding MainCommand}" MouseAction="{Binding MainCommand.MouseAction}" /> </Window.InputBindings> <Grid> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Button Grid.Row="0" Content="Click" Command="{Binding MainCommand}" /> <TextBlock Grid.Row="1" Text="{Binding MainText}" /> </Grid>
Závěrem
Jak můžete vidět v ukázce, je možné už ve ViewModelu nadefinovat klávesové zkratky nebo akce myší a tyto napojit na daný příkaz. Tím máme snadnou cestu k tomu, abychom uživateli nabídli možnost tyto klávesové zkratky snadno změnit a uložit si je do obvyklého uložiště nastavení.
Komentáře