XAML.cz Magazín moderních technologií založených na XAML

Novinky ve WPF 4 - InputBinding

Napsáno pro WPF od Jarda Jirava  [12.04.2010]

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

ukládám komentář, vyčkejte prosím..
  1. Buďte první, kdo napíše komentář.

@xamlcz

  • RT @jvanrhyn: XAML, It's a bit like olives. Takes a while to get used to. But once you're used to it. It is actually pretty good. <3 XAML
  • RT @moser_christian: WPF Inspector 0.9.7 is released. It supports .NET 3.5 and 4.0 The project is now open source and available on CodeP ...
  • Jeff Handley oznámil vydání WCF RIA Services v.1.0 SP1 RTM http://bit.ly/gOgckn ke stažení na http://bit.ly/gVAXdK
  • jedna výzva pro Brno. Byl někdo z vás na přednášce o RIA v MS Akvárku? Dejte o sobě vědět. Děkuji
  • také jste uvažovali o tom, že zkusíte na projekt použít Caliburn Micro nebo naopak Prism 4? A co tak obojí, šlo by to nebo ne? Již brzy