wtorek, 8 maja 2012

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

WPF oferuje znacznie bardziej rozbudowany system obsługi zdarzeń niż ten znany z WindowsForms. WPF udostępnia tzw. routet events, mechanizm umożliwiający przechwytywanie zdarzenia na wielu poziomach hierarchii drzewa wizualnego.

3 typy routed events:
  • Direct Events - zdarzenia, które są najbliższe tym znanym z WindowsForms. Zdarzenie to jest wywoływane i obsługiwane tylko u źródła, przykład: MouseLeave'
  • Bubbling events - wywołane najpierw u źródła, a następnie przechodzi w dół drzewa wizualnego. Przykładem może być okno w którym na panelu leży label. Zdarzenie MouseDown wywołane na labelu, przejdzie na panel a następnie na okno. Na każdym z tych poziomów możemy je obsłużyć.
  • Tuneling Events - jest to zdarzenie działające odwrotnie do Bubbling event, swoją drogę rozpoczyna w najstarszym przodku, aż do kontrolki która faktycznie je wywołała
Zdarzenia typu Tunelling są w WPF oznaczane słówkiem Preview np PreviewKeyDown.
Zdatzenie typu Tunelling są zawsze wykonywane przed zdarzeniami typu Bubbling.


Routet events args
Klasa ta zawiera bogate informacje o zdarzeniu oraz jego źródła. Właściwości które można w niej znaleźć:
  • Handled - determinuje czy zdarzenie zostało obsłużone. Można dzięki temu zatrzymać dalszy postęp bubblingu lub tunelingu
  • OriginalSource - zwraca informację o źródle skąd pochodzi zdarzenie. Przeważnie zwraca to samo co właściwość Source, dla kontrolek typu composite może być to jednak inna wartość
  • RoutedEvent - w przypadku łapania więcej niż jednego zdarzenia za pomocą tego samego uchwytu, można dzięki tej właściwości zidentyfikować zdarzenie
  • Source - zwraca obiekt który wywołał zdarzenie


Dodawanie uchwytu
Uchwyt do zdarzenia najlepiej dodać w XAML-u:


Code:
<Button VerticalAlignment="Top" Click="button1_Click">Button</Button>

Istnieje możliwość przypięcia zdarzenia do kontrolki, która w normalnych warunkach go nie rzuca. Są to tzw. Attached Events. Dla przykładu można przypiąć zdarzenie kliknięcia Gridowi, który posiada button:


Code:
    <Grid Button.Click="Grid_Click">
        <Button Name="button1" VerticalAlignment="Top" >Button</Button>
    </Grid>



EventManager
Jest to klasa, która zajmuje się rejestracją wszystkich zdarzeń w aplikacji WPF. Właściwości:
  • GetRoutedEvents - zwraca tablicę wszystkich zaarejestrowanych Routed Events
  • GetRoutedEventsForOwner - zwraca tablicę wszystkich zarejestrowanych zdarzeń dla podanego obiektu
  • RegisterClassHandler - rejestruje uchwyt na poziomie klasy
  • RegisterRoutedEvent - rejestruje uchwyt na poziomie instancji klasy


Tworzenie nowego Routed Event
1. Tworzymy publiczne, tylko do odczytu zdarzenie:


Code:
public static readonly RoutedEvent MyEvent;

2. Tworzymy wrapper dla Routed Event:


Code:
        public event RoutedEventHandler MyEventWrapper
        {
            add
            {
                AddHandler(MyEvent, value);
            }
            remove
            {
                RemoveHandler(MyEvent, value);
            }
        }

3. Używając EventManager rejestrujemy zdarzenie w konstruktorze klasy, która będzie go używać:


Code:
EventManager.RegisterRoutedEvent("MyEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Button));

Podajemy kolejno: nazwę zdarzenia, rodzaj, typ delegaty, klasę która jest jego właścicielem.
Wywoływanie zdarzenia w kodzie polega na stworzeniu obiektu klasy RoutedEventArgs, a następnie wywołanie zdarzenia za pomocą metody RaiseEvent:


Code:
            RoutedEventArgs myEventArgs = new RoutedEventArgs(myControl.myNewEvent);
            RaiseEvent(myEventArgs);



Tworzenie uchwytu na poziomie klasy
Uchwyt taki wywoływany jest dla każdej klasy żądanego typu i jest wywoływany przed uchwytem na poziomie instancji klasy. Tworzenie takiego uchwytu:

1. Tworzymy statyczną metodę o takiej samej sygnaturze jak zdarzenie:


Code:
private static void SuperClickHandlerMethod(object sender, RoutedEventArgs e)
{
//obsługa
}

2. W statycznym konstruktorze, który będzie korzystał z tego zdarzenia tworzymy delegate do metody:


Code:
RoutedEventHandler MyHandler = new RoutedEventHandler(SuperClickHandlerMethod);

3. Także w statycznym konstruktorze rejestrujemy uchwyt:


Code:
EventManager.RegisterClassHandler(typeof(Button),
SuperClickEvent,MyHandler);



Zdarzenia na poziomie aplikacji
Klasa Application zawiera standardowe zdarzenia, które mogą zajść podczas korzystania z aplikacji. Wybrane z nich:
  • Activated - wywoływane podczas pierwszego uruchomienia aplikacji jak i przy przejściu z innej do naszej
  • Deactivated - wywołuje się w momencie przejścia do innej aplikacji
  • DispatcherUnhandledException - Wywoływany w momencie gdy wyjątek nie zostanie nigdzie obsłużony
  • Exit - wywołuje się niezależnie od powodu zamknięcia aplikacji
  • SessionEnding - wywoływany w momencie gdy użytkownik wylogowuje się lub zamyka komputer
  • Startup - wywoływany w momencie uruchamiania aplikacji
 Instrukcja tworzenia uchwytu na poziomie aplikacji:
 1. W pliku App.xaml dodajmy zdarzenie:


Code:
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml" Startup="App_Startup">

2. W kodzie C# obsługujemy je:


Code:
void App_Startup(object sender, StartupEventArgs e)
{
// obsługa
}

Brak komentarzy:

Prześlij komentarz