wtorek, 8 maja 2012

70-511 Rozdział 2 - Zdarzenia i komendy - komendy

Komendy to nowy sposób obsługi często powtarzanych czynności. Przykładami komend w WPF są np. Copy, Paste, Cut.
Wbudowane komendy znajdziemy w jednej z 5 statycznych klas:
  • ApplicationCommands
  • ComponentCommands
  • EditingCommands
  • MediaCommands
  • NavigationCommands
Procedura implementacji komendy:
  1. Decyzja czy będzie używana jedna z dostępnych (zaimplementowanych już) komend czy będzie to stworzona nowa implementacja
  2. Skojarzenie komendy z kontrolkami
  3. Stworzenie metody obsługującej komendę
  4. Stworzenie kontrolki CommandBinding bindującej komendę z uchwytem
  5. Dodanie bindingu komendy do kolekcji Commands okna, tam gdzie wywoływana jest komenda

Skojarzenie komendy z kontrolką
Wiele kontrolek implementuje interfejs ICommandSource dzięki czemu udostępniają właściwość Command, np. Button. Komenda jest wywoływana w tym przypadku po wciśnięciu przycisku:


Code:
<Button Command="ApplicationCommands.Find">Button</Button>


Wywołanie komendy za pomocą gestów
Komendę można także skojarzyć z gestami myszy czy zdarzeniami klawiatury:


Code:
ApplicationCommands.Find.InputGestures.Add(new
MouseGesture(MouseAction.LeftClick, ModifierKeys.Control));
ApplicationCommands.Find.InputGestures.Add(new
KeyGesture(Key.Q, ModifierKeys.Control));



Wywołanie komendy z kodu:
Jeżeli kontrolka nie udostępnia właściwości Command, można zawartość procedury komendy wywołać bezpośrednio z kodu:


Code:
ApplicationCommands.Find.Execute(aParameter, TargetControl);

aParameter - parametr komendy (jeżeli nie jest wymagany można przesłać null)
TargetControl - tutaj zostanie rozpoczęte poszukiwanie metodą bubble w poszukiwaniu CommandBinding.


Uchwyty komend
Sygnatura uchwytu do komendy:


Code:
private void myCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
// obsługa
}




Command Bindings
Obiekt tego typu skleja całą architekturę komend - łączy komendę z jej uchwytem. Dodając obiekt typu CommandBinding do kolekcji CommandBindings okna lub innej kontrolki umożliwia wywołanie kodu w momencie zadziałania komendy. Poniżej kod umożliwiający stworzenie i rejestrację CommandBinding:


Code:
CommandBinding abinding = new CommandBinding();
abinding.Command = ApplicationCommands.Find;
abinding.Executed += new ExecutedRoutedEventHandler(myCommandHandler);
this.CommandBindings.Add(abinding);


Command Bubbling
Każda kontrolka posiada kolekcję CommandBindings. Jest to związane z tym iż podobnie jak w Routed Events tu także występuje mechanizm bubblingu. Przerwanie tego mechanizmu przebiega tak samo jak dla zdarzeń.


Wyłączanie komend
Jeżeli komenda nie uczestniczy w bindingu automatycznie jest wyłączona. Innym sposobem jest użycie metody CanExecute która zwraca wartość typu bool mówiącą czy dana komenda jest możliwa do wykonania czy też nie.
Aby przechwycić zdarzenie CanExecute:
1. Tworzymy metodę która determinuje czy można wykonać komendę:


Code:
bool canExecute;
void abinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = canExecute;
}

2. Dla bindingu dodajemy obsługę zdarzenia CanExecute:


Code:
abinding.CanExecute += new CanExecuteRoutedEventHandler(abinding_CanExecute);

Można także to zrobić w kodzie XAML:


Code:
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Find"
Executed="CommandBinding_Executed"
CanExecute="abinding_CanExecute" />
</Window.CommandBindings>



Tworzenie własnych komend
W tym przypadku Microsoft zaleca stworzenie statycznej klasy która eksponuje komendę do użycia:


Code:
    public static class MyCommands
    {
        private static RoutedUICommand launch_command;

        static MyCommands()
        {
            InputGestureCollection myInputGestures = new
                InputGestureCollection();
            myInputGestures.Add(new KeyGesture(Key.L, ModifierKeys.Control));
            launch_command = new RoutedUICommand("Launch", "Launch",
                                                 typeof (MyCommands), myInputGestures);
        }

        public RoutedUICommand Launch
        {
            get { return launch_command; }
        }
    }

Brak komentarzy:

Prześlij komentarz