Přehled směrovaných událostí (WPF .NET)

Windows Presentation Foundation (WPF) vývojáři aplikací a autoři komponent můžou pomocí směrovaných událostí rozšířit události prostřednictvím stromu elementů a vyvolat obslužné rutiny událostí u více naslouchacích procesů ve stromu. Tyto funkce nejsou nalezeny v událostech modulu CLR (Common Language Runtime). Několik událostí WPF je směrovaných událostí, například ButtonBase.Click. Tento článek popisuje základní koncepty směrovaných událostí a nabízí pokyny k tomu, kdy a jak reagovat na směrované události.

Důležité

Dokumentace k desktopové příručce pro .NET 6 a .NET 5 (včetně .NET Core 3.1) je ve konstrukci.

Požadavky

Tento článek předpokládá základní znalost modulu CLR (Common Language Runtime), objektově orientovaného programování a toho, jak lze rozložení elementu WPF konceptualizovat jako strom. Pokud chcete postupovat podle příkladů v tomto článku, pomůže vám to, když znáte jazyk XAML (Extensible Application Markup Language) a víte, jak psát aplikace WPF.

Co je směrovaná událost?

Směrované události můžete zvážit z hlediska funkčnosti nebo implementace:

  • Z hlediska funkčnosti je směrovaná událost typem události, která může vyvolat obslužné rutiny u více naslouchacích procesů ve stromu elementů, nejen ve zdroji událostí. Naslouchací proces událostí je prvek, ve kterém je připojena a vyvolána obslužná rutina události. Zdrojem událostí je prvek nebo objekt, který původně vyvolal událost.

  • Z hlediska implementace je směrovaná událost událost zaregistrovaná v systému událostí WPF, která je zajištěna instancí RoutedEvent třídy a zpracována systémem událostí WPF. Směrovaná událost se obvykle implementuje pomocí obálky události CLR, která umožňuje připojení obslužných rutin v XAML a v kódu za událostí CLR.

Aplikace WPF obvykle obsahují mnoho prvků, které byly deklarovány v XAML nebo vytvoření instance v kódu. Prvky aplikace existují ve stromu elementů. V závislosti na tom, jak je směrovaná událost definována, když je událost vyvolána na zdrojovém prvku:

  • Bubliny prochází stromem prvků ze zdrojového elementu do kořenového prvku, což je obvykle stránka nebo okno.
  • Tuneluje přes strom elementů z kořenového elementu do zdrojového prvku.
  • Neprochází stromem prvků a vyskytuje se pouze u zdrojového prvku.

Zvažte následující částečný strom elementů:

<Border Height="30" Width="200" BorderBrush="Gray" BorderThickness="1">
    <StackPanel Background="LightBlue" Orientation="Horizontal" Button.Click="YesNoCancelButton_Click">
        <Button Name="YesButton">Yes</Button>
        <Button Name="NoButton">No</Button>
        <Button Name="CancelButton">Cancel</Button>
    </StackPanel>
</Border>

Strom elementu se vykresluje, jak je znázorněno:

Yes, No, and Cancel buttons.

Každá ze tří tlačítek je potenciálním Click zdrojem událostí. Když kliknete na jedno z tlačítek, vyvolá událost, která se z tlačítka zvětšuje Click na kořenový prvek. Border Prvky Button nemají připojené obslužné rutiny událostí, ale to StackPanel znamená. Další prvky ve stromu, které se nezobrazují, mají Click také připojené obslužné rutiny událostí. Click Když událost dosáhne StackPanel prvku, systém událostí WPF vyvolá obslužnou rutinuYesNoCancelButton_Click, která je k ní připojena. Trasa události události v příkladu Click je: Button ->StackPanel ->Border -> po sobě jdoucí nadřazené prvky.

Poznámka

Element, který původně vyvolal směrovanou událost, je identifikován jako RoutedEventArgs.Source v parametrech obslužné rutiny události. Naslouchací proces událostí je prvek, ve kterém je obslužná rutina události připojena a vyvolána, a je identifikován jako odesílatel v parametrech obslužné rutiny události.

Scénáře nejvyšší úrovně pro směrované události

Tady jsou některé scénáře, které motivovaly koncept směrovaných událostí a odlišovaly ho od typické události CLR:

  • Složení ovládacích prvků a zapouzdření: Různé ovládací prvky ve WPF mají bohatý model obsahu. Obrázek můžete například umístit do objektu Button, který efektivně rozšiřuje vizuální strom tlačítka. Přidaný obrázek ale nesmí přerušit chování tlačítka, které musí reagovat, když uživatel klikne na pixely obrázku.

  • Jednotlivé body přílohy obslužné rutiny: Můžete zaregistrovat obslužnou rutinu pro událost každého tlačítka Click , ale se směrovanými událostmi můžete připojit jednu obslužnou rutinu, jak je znázorněno v předchozím příkladu XAML. Díky tomu můžete změnit strom elementu pod jedinečnou obslužnou rutinou, jako je přidání nebo odebrání dalších tlačítek, aniž byste museli zaregistrovat událost jednotlivých tlačítek Click . Při vyvolání Click události může logika obslužné rutiny určit, odkud událost pochází. Následující obslužná rutina zadaná v dříve zobrazeném stromu elementů XAML obsahuje tuto logiku:

    private void YesNoCancelButton_Click(object sender, RoutedEventArgs e)
    {
        FrameworkElement sourceFrameworkElement = e.Source as FrameworkElement;
        switch (sourceFrameworkElement.Name)
        {
            case "YesButton":
                // YesButton logic.
                break;
            case "NoButton":
                // NoButton logic.
                break;
            case "CancelButton":
                // CancelButton logic.
                break;
        }
        e.Handled = true;
    }
    
    Private Sub YesNoCancelButton_Click(sender As Object, e As RoutedEventArgs)
        Dim frameworkElementSource As FrameworkElement = TryCast(e.Source, FrameworkElement)
    
        Select Case frameworkElementSource.Name
            Case "YesButton"
                ' YesButton logic.
            Case "NoButton"
                ' NoButton logic.
            Case "CancelButton"
                ' CancelButton logic.
        End Select
    
        e.Handled = True
    End Sub
    
  • Zpracování tříd: Směrované události podporují obslužnou rutinu události třídy , kterou definujete ve třídě. Obslužné rutiny třídy zpracovávají událost před všemi obslužné rutiny instance pro stejnou událost v libovolné instanci třídy.

  • Odkazování na událost bez reflexe: Každá směrovaná událost vytvoří RoutedEvent identifikátor pole, který poskytuje robustní techniku identifikace událostí, která nevyžaduje statické nebo běhu odraz k identifikaci události.

Implementace směrovaných událostí

Směrovaná událost je událost zaregistrovaná v systému událostí WPF, která je zajištěna instancí RoutedEvent třídy a zpracována systémem událostí WPF. Instance RoutedEvent získaná z registrace je obvykle uložena jako public static readonly člen třídy, která ji zaregistrovala. Tato třída se označuje jako třída "owner". Směrovaná událost obvykle implementuje identickou událost CLR "wrapper". Obálka událostí CLR obsahuje add a remove přístupové objekty, které umožňují připojení obslužných rutin v XAML a v kódu prostřednictvím syntaxe událostí specifických pro jazyk. A addremove přístupové objekty přepíší implementaci CLR a volají směrované události AddHandler a RemoveHandler metody. Směrovaný mechanismus zálohování událostí a připojení je koncepční podobný tomu, jak je vlastnost závislostí vlastnost CLR, která je podporována DependencyProperty třídou a zaregistrovaná v systému vlastností WPF.

Následující příklad zaregistruje Tap směrovanou událost, uloží vrácenou RoutedEvent instanci a implementuje obálku události CLR.

// Register a custom routed event using the Bubble routing strategy.
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
    name: "Tap",
    routingStrategy: RoutingStrategy.Bubble,
    handlerType: typeof(RoutedEventHandler),
    ownerType: typeof(CustomButton));

// Provide CLR accessors for adding and removing an event handler.
public event RoutedEventHandler Tap
{
    add { AddHandler(TapEvent, value); }
    remove { RemoveHandler(TapEvent, value); }
}
' Register a custom routed event using the Bubble routing strategy.
Public Shared ReadOnly TapEvent As RoutedEvent = EventManager.RegisterRoutedEvent(
    name:="Tap",
    routingStrategy:=RoutingStrategy.Bubble,
    handlerType:=GetType(RoutedEventHandler),
    ownerType:=GetType(CustomButton))

' Provide CLR accessors for adding and removing an event handler.
Public Custom Event Tap As RoutedEventHandler
    AddHandler(value As RoutedEventHandler)
        [AddHandler](TapEvent, value)
    End AddHandler

    RemoveHandler(value As RoutedEventHandler)
        [RemoveHandler](TapEvent, value)
    End RemoveHandler

    RaiseEvent(sender As Object, e As RoutedEventArgs)
        [RaiseEvent](e)
    End RaiseEvent
End Event

Strategie směrování

Směrované události používají jednu ze tří strategií směrování:

  • Bublování: Zpočátku se vyvolá obslužné rutiny událostí ve zdroji události. Směrovaná událost pak směruje na po sobě jdoucí nadřazené elementy a vyvolá jejich obslužné rutiny událostí, dokud nedosáhne kořen stromu elementu. Většina směrovaných událostí používá strategii směrování bublování. Směrované události bublování se obecně používají k sestavě změn vstupu nebo stavu ze složených ovládacích prvků nebo jiných prvků uživatelského rozhraní.

  • Tunelování: Zpočátku se vyvolá obslužné rutiny událostí v kořenovém adresáři stromu elementu. Směrovaná událost pak směruje do následných podřízených prvků a vyvolá jejich obslužné rutiny událostí, dokud nedosáhne zdroje události. Události, které sledují trasu tunelování, se také označují jako události preview . Vstupní události WPF se obecně implementují jako dvojice náhledu a bublání.

  • Direct: Vyvolá se pouze obslužné rutiny událostí ve zdroji událostí. Tato strategie bez směrování je analogická k událostem rozhraní uživatelského rozhraní model Windows Forms, což jsou standardní události CLR. Na rozdíl od událostí CLR podporují přímé směrované události zpracování tříd a můžou je používat EventSetters a EventTriggers.

Proč používat směrované události?

Jako vývojář aplikací nemusíte vždy vědět ani se starat o to, že se událost, kterou zpracováváte, implementuje jako směrovaná událost. Směrované události mají zvláštní chování, ale toto chování je z velké části neviditelné, pokud zpracováváte událost u prvku, který ho vyvolal. Směrované události jsou však relevantní, pokud chcete připojit obslužnou rutinu události k nadřazeného prvku, aby bylo možné zpracovat události vyvolané podřízenými prvky, jako je například ve složeného ovládacího prvku.

Směrované naslouchací procesy událostí nepotřebují směrované události, které zpracovávají, aby byly členy své třídy. Libovolný UIElement nebo ContentElement může být naslouchací proces událostí pro libovolnou směrovanou událost. Vzhledem k tomu, že vizuální prvky pocházejí z UIElement nebo ContentElement, můžete směrované události použít jako koncepční "rozhraní", které podporuje výměnu informací o událostech mezi různorodé prvky v aplikaci. Koncept rozhraní pro směrované události se vztahuje zejména na vstupní události.

Směrované události podporují výměnu informací o událostech mezi prvky podél trasy události, protože každý naslouchací proces má přístup ke stejné instanci dat událostí. Pokud jeden prvek změní něco v datech události, tato změna je viditelná pro další prvky v trase události.

Kromě aspektu směrování se můžete rozhodnout implementovat směrovanou událost místo standardní události CLR z těchto důvodů:

  • Některé funkce stylů a šablon WPF, jako jsou EventSetters a EventTriggers, vyžadují, aby odkazovaná událost byla směrovaná událost.

  • Směrované události podporují obslužné rutiny událostí třídy , které zpracovávají událost před všemi obslužné rutiny instance pro stejnou událost u jakékoli instance naslouchacího procesu třídy. Tato funkce je užitečná při návrhu řízení, protože obslužná rutina třídy může vynutit chování třídy řízené událostmi, které nelze omylem potlačit obslužnou rutinou instance.

Připojení a implementace obslužné rutiny směrované události

V XAML připojíte obslužnou rutinu události k elementu deklarací názvu události jako atribut elementu naslouchacího procesu událostí. Hodnota atributu je název metody obslužné rutiny. Metoda obslužné rutiny musí být implementována v částečné třídě kódu za stránkou XAML. Naslouchací proces událostí je prvek, ve kterém je obslužná rutina události připojena a vyvolána.

U události, která je členem (zděděným nebo jiným) třídy naslouchacího procesu, můžete připojit obslužnou rutinu následujícím způsobem:

<Button Name="Button1" Click="Button_Click">Click me</Button>

Pokud událost není členem třídy naslouchacího procesu, musíte použít kvalifikovaný název události ve formě <owner type>.<event name>. Protože StackPanel třída například neimplementuje Click událost, pro připojení obslužné rutiny k StackPanelClick události, která bublinuje až na tento prvek, budete muset použít kvalifikovanou syntaxi názvu události:

<StackPanel Name="StackPanel1" Button.Click="Button_Click">
    <Button>Click me</Button>
</StackPanel>

Podpis metody obslužné rutiny události v kódu za musí odpovídat typu delegáta pro směrovanou událost. Parametr sender delegáta RoutedEventHandler události Click určuje prvek, ke kterému je obslužná rutina události připojena. Parametr args delegáta RoutedEventHandler obsahuje data události. Kompatibilní implementace za kódem pro obslužnou rutinu Button_Click události může být:

private void Button_Click(object sender, RoutedEventArgs e)
{
    // Click event logic.
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
    ' Click event logic.
End Sub

I když RoutedEventHandler je základní delegát směrované obslužné rutiny událostí, některé ovládací prvky nebo scénáře implementace vyžadují různé delegáty, kteří podporují specializovanější data událostí. Například pro DragEnter směrovanou událost by měla obslužná rutina implementovat delegáta DragEventHandler . Tímto způsobem může kód obslužné rutiny přistupovat k DragEventArgs.Data vlastnosti v datech událostí, která obsahuje datovou část schránky z operace přetažení.

Syntaxe XAML pro přidání směrovaných obslužných rutin událostí je stejná jako u standardních obslužných rutin událostí CLR. Další informace o přidávání obslužných rutin událostí v XAML naleznete v jazyce XAML ve WPF. Úplný příklad připojení obslužné rutiny události k elementu pomocí XAML naleznete v tématu Zpracování směrované události.

Pokud chcete připojit obslužnou rutinu události směrované události k elementu pomocí kódu, obecně máte dvě možnosti:

  • Přímo volejte metodu AddHandler . Obslužné rutiny směrovaných událostí lze vždy připojit tímto způsobem. Tento příklad připojí obslužnou rutinu Click události k tlačítku pomocí AddHandler metody:

    Button1.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Button_Click));
    
    Button1.[AddHandler](ButtonBase.ClickEvent, New RoutedEventHandler(AddressOf Button_Click))
    

    Připojení obslužné rutiny události tlačítka Click k jinému prvku v trase události, například pojmenované StackPanelStackPanel1:

    StackPanel1.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Button_Click));
    
    StackPanel1.[AddHandler](ButtonBase.ClickEvent, New RoutedEventHandler(AddressOf Button_Click))
    
  • Pokud směrovaná událost implementuje obálku událostí CLR, použijte syntaxi událostí specifickou pro jazyk a přidejte obslužné rutiny událostí stejně jako u standardní události CLR. Většina existujících směrovaných událostí WPF implementuje obálku CLR, čímž povolí syntaxi událostí specifickou pro jazyk. Tento příklad připojí obslužnou rutinu Click události k tlačítku pomocí syntaxe specifické pro jazyk:

    Button1.Click += Button_Click;
    
    AddHandler Button1.Click, AddressOf Button_Click
    

Příklad připojení obslužné rutiny události v kódu naleznete v tématu Postup přidání obslužné rutiny události pomocí kódu. Pokud kódujete v Visual Basic, můžete také pomocí klíčového Handles slova přidat obslužné rutiny jako součást deklarací obslužné rutiny. Další informace najdete v tématu Visual Basic a zpracování událostí WPF.

Koncept zpracování

Všechny směrované události sdílejí společnou základní třídu pro data událostí, což je RoutedEventArgs třída. Třída RoutedEventArgs definuje logickou Handled vlastnost. Účelem Handled vlastnosti je umožnit, aby jakákoli obslužná rutina události podél trasy události označovala směrovanou událost jako zpracována. Pokud chcete událost označit jako obslužnou, nastavte hodnotu Handled v true kódu obslužné rutiny události.

Hodnota Handled ovlivňuje způsob zpracování směrované události při cestě po trase události. Pokud Handled jsou true ve sdílených datech událostí směrované události, obslužné rutiny připojené k dalším prvkům podél trasy události se obvykle pro tuto konkrétní instanci události nevyvolávají. U nejběžnějších scénářů obslužné rutiny označení události jako zpracovávané efektivně zastaví následné obslužné rutiny podél trasy události, ať už obslužné rutiny instance nebo třídy, z reakce na danou konkrétní instanci události. Ve výjimečných případech, kdy potřebujete obslužnou rutinu události k reakci na směrované události označené jako zpracovávané, můžete:

Koncept Handled může ovlivnit způsob návrhu aplikace a kódu obslužných rutin událostí. Můžete konceptualizovat Handled jako jednoduchý protokol pro zpracování směrovaných událostí. Způsob použití tohoto protokolu je na vás, ale očekávané použití parametru Handled je:

  • Pokud je směrovaná událost označena jako zpracována, není nutné ji znovu zpracovat jinými prvky podél trasy.

  • Pokud směrovaná událost není označená jako obslužná, pak naslouchací procesy dříve v trase události nemají obslužnou rutinu události nebo žádný z registrovaných obslužných rutin neodpověděl na událost způsobem, který zdůvodňuje označení události jako zpracovávané. Obslužné rutiny v aktuálním naslouchacím procesu mají tři možné kurzy akce:

    • Nechejte vůbec žádnou akci. Událost zůstává neošetřená a směruje se na další naslouchací proces ve stromu.

    • Spusťte kód v reakci na událost, ale ne v rozsahu, který zdůvodňuje označení události jako zpracovávané. Událost zůstává neošetřená a směruje se na další naslouchací proces ve stromu.

    • Spusťte kód v reakci na událost v rozsahu, který zdůvodňuje označení události jako zpracovávané. Označte událost jako zpracovánou v datech události. Událost stále směruje na další naslouchací proces ve stromu, ale většina naslouchacích procesů nevyvolá další obslužné rutiny. Výjimkou jsou naslouchací procesy s obslužnými rutinami, které byly speciálně registrovány s handledEventsToo nastavenou na truehodnotu .

Další informace o zpracování směrovaných událostí naleznete v tématu Označení směrovaných událostí jako zpracovaných a zpracování tříd.

I když vývojáři, kteří zpracovávají pouze bublající událost směrovanou událost na objektu, který ho vyvolal, nemusí být znepokojeni jinými naslouchacími procesy, je vhodné událost označit jako zpracovávanou. Tím zabráníte neočekáženým vedlejším účinkům, pokud prvek dále podél trasy události obsahuje obslužnou rutinu pro stejnou směrovanou událost.

Obslužné rutiny tříd

Obslužné rutiny směrovaných událostí mohou být obslužné rutiny instance nebo obslužné rutiny tříd . Obslužné rutiny třídy pro danou třídu jsou vyvolány před jakoukoli obslužnou rutinou instance reagující na stejnou událost na jakékoli instanci této třídy. Vzhledem k tomuto chování jsou směrované události označeny jako popisované, často se označují jako takové v rámci obslužných rutin tříd. Existují dva typy obslužných rutin tříd:

Některé ovládací prvky WPF mají vlastní zpracování tříd pro určité směrované události. Zpracování tříd může dát vnější vzhled, že směrovaná událost není nikdy vyvolána, ale ve skutečnosti je označena jako zpracována obslužnou rutinou třídy. Pokud potřebujete, aby obslužná rutina události reagovala na obslužnou událost, můžete obslužnou rutinu zaregistrovat s nastavenou handledEventsTootruena hodnotu . Další informace o implementaci vlastních obslužných rutin tříd nebo práci s nežádoucím zpracováním tříd naleznete v tématu Označení směrovaných událostí jako zpracovaných a zpracování tříd.

Připojené události ve WPF

Jazyk XAML také definuje speciální typ události označované jako připojená událost. Připojené události lze použít k definování nové směrované události ve třídě, která není elementem, a vyvolat tuto událost u libovolného prvku ve stromu. K tomu je nutné zaregistrovat připojenou událost jako směrovanou událost a zadat konkrétní záložní kód , který podporuje funkce připojených událostí. Vzhledem k tomu, že připojené události jsou registrovány jako směrované události, při vyvolání u elementu, který šíří přes strom elementu.

V syntaxi XAML je připojená událost určena názvem události a typem vlastníka ve formě <owner type>.<event name>. Vzhledem k tomu, že název události je kvalifikovaný s názvem jeho typu vlastníka, syntaxe umožňuje připojit událost k libovolnému prvku, který lze vytvořit instanci. Tato syntaxe se vztahuje také na obslužné rutiny pro běžné směrované události, které se připojují k libovolnému prvku podél trasy události. Obslužné rutiny pro připojené události v kódu za sebou můžete také připojit voláním AddHandler metody na objektu, ke kterému se má obslužná rutina připojit.

Vstupní systém WPF používá připojené události široce. Téměř všechny připojené události se však zobrazí jako ekvivalentní ne připojené směrované události prostřednictvím základních prvků. Zřídka budete používat nebo zpracovávat připojené události přímo. Je například jednodušší zpracovat podkladovou připojenou Mouse.MouseDownUIElement událost u ekvivalentní UIElement.MouseDown směrované události, než pomocí připojené syntaxe událostí v XAML nebo kódu.

Další informace o připojených událostech ve WPF naleznete v tématu Přehled připojených událostí.

Kvalifikované názvy událostí v XAML

Syntaxe <owner type>.<event name> kvalifikuje název události s názvem jeho typu vlastníka. Tato syntaxe umožňuje připojit událost k libovolnému prvku, nejen k prvkům, které implementují událost jako člena jejich třídy. Syntaxe je použitelná při připojování obslužných rutin v XAML pro připojené události nebo směrované události na libovolné prvky podél trasy události. Představte si scénář, ve kterém chcete připojit obslužnou rutinu k nadřazené elementu, aby bylo možné zpracovávat směrované události vyvolané podřízenými elementy. Pokud nadřazený prvek nemá směrovanou událost jako člen, budete muset použít syntaxi kvalifikovaného názvu události. Příklad:

<StackPanel Name="StackPanel1" Button.Click="Button_Click">
    <Button>Click me</Button>
</StackPanel>

V příkladu je nadřazený element naslouchací proces, do kterého je přidána obslužná rutina události .StackPanel Click Směrovaná událost je však implementována a vyvolána ve ButtonBase třídě a k dispozici pro Button třídu prostřednictvím dědičnosti. Button Přestože třída "vlastní" Click událost, směrovaný systém událostí umožňuje obslužné rutiny pro všechny směrované události být připojeny k libovolné UIElementContentElement nebo instance naslouchací proces, který by jinak mohl mít obslužné rutiny pro událost CLR. Výchozí xmlns obor názvů pro tyto kvalifikované názvy atributů událostí je obvykle výchozí obor názvů WPF xmlns , ale můžete také zadat předpony oborů názvů pro vlastní směrované události. Další informace o xmlnsoborech názvů XAML a mapování oboru názvů pro WPF XAML.

Události vstupu WPF

Jednou z častých aplikací směrovaných událostí v rámci platformy WPF je vstupní události. Podle konvence mají směrované události WPF, které následují tunelovou trasu, název, který má předponu Preview. Předpona náhledu značí, že se událost náhledu dokončí před spuštěním spárované bublající události. Vstupní události se často scházejí ve dvojicích, přičemž jedna je událost náhledu a druhá probublácená směrovaná událost. Příklad: PreviewKeyDown a KeyDown. Dvojice událostí sdílejí stejnou instanci dat události, pro PreviewKeyDown kterou a KeyDown je typu KeyEventArgs. V některých případech mají vstupní události pouze probubující verzi nebo pouze přímou směrovanou verzi. V dokumentaci k rozhraní API témata směrovaných událostí křížově odkazují na páry směrovaných událostí a objasňují strategii směrování pro každou směrovanou událost.

Vstupní události WPF, které jsou součástí párů, jsou implementovány tak, aby jedna akce uživatele ze vstupního zařízení, například stisknutí tlačítka myši, vyvolala náhled a vybuchlující směrované události v posloupnosti. Nejprve se vyvolá událost preview a dokončí její trasu. Po dokončení události náhledu se vyvolá bublinová událost a dokončí její trasu. Volání RaiseEvent metody v implementující třídě, která vyvolá bublující událost znovu použije data události z události náhledu pro probubující událost.

Vstupní událost náhledu, která je označená jako zpracovávaná, nevyvolá žádné normálně registrované obslužné rutiny událostí pro zbytek trasy preview a spárovaná bublující událost se nevyvolá. Toto chování zpracování je užitečné pro návrháře složených ovládacích prvků, kteří chtějí, aby vstupní události založené na testu nebo vstupní události založené na fokusu byly hlášeny na nejvyšší úrovni jejich ovládacího prvku. Prvky nejvyšší úrovně ovládacího prvku mají možnost zpracovávat události náhledu z dílčích součástí ovládacího prvku, aby je "nahradily" událostí specifickou pro řízení nejvyšší úrovně.

Pokud chcete ilustrovat, jak funguje zpracování vstupních událostí, zvažte následující příklad vstupní události. Na následujícím obrázku stromu je zdrojem PreviewMouseDownMouseDown jak spárovaných událostí, leaf element #2 tak i spárovaných událostí:

Event routing diagram.

Pořadí zpracování událostí po akci myši u prvku list č. 2 je:

  1. PreviewMouseDown tunneling event on the root element.
  2. PreviewMouseDown tunneling event on intermediate element #1.
  3. PreviewMouseDown tunelovací událost u elementu leaf #2, což je zdrojový prvek.
  4. MouseDown bublující událost u elementu list č. 2, což je zdrojový prvek.
  5. MouseDown bublující událost u zprostředkujícího prvku č. 1.
  6. MouseDown bublující událost na kořenovém prvku.

Delegát směrované obslužné rutiny události poskytuje odkazy na objekt, který vyvolal událost, i objekt, ve kterém byla vyvolána obslužná rutina. Objekt, který původně vyvolal událost, je hlášen vlastností Source v datech události. Objekt, ve kterém byla vyvolána obslužná rutina, je hlášen parametrem odesílatele . U jakékoli instance směrované události se objekt, který vyvolal událost, nezmění, protože událost prochází stromem elementu, ale sender to dělá. V krocích 3 a 4 předchozího diagramu se jedná sender o Source stejný objekt.

Pokud obslužná rutina vstupní události dokončí logiku specifickou pro aplikaci potřebnou k vyřešení události, měli byste vstupní událost označit jako zpracovánou. Jakmile je vstupní událost označená Handled, obslužné rutiny dále podél trasy události se nevyvolávají. Vstupní obslužné rutiny událostí, které jsou zaregistrované v handledEventsToo sadě true parametrů, se však vyvolá i v případě, že je událost označena jako zpracována. Další informace najdete v tématu Náhled událostí a označení směrovaných událostí jako zpracovaných a zpracování tříd.

Koncept párů událostí ve verzi Preview a bublinových událostí se sdílenými daty událostí a sekvenčním zvýšením události verze Preview se pak vztahuje pouze na některé vstupní události WPF a ne na všechny směrované události. Pokud implementujete vlastní vstupní událost pro řešení pokročilého scénáře, zvažte postup páru vstupních událostí WPF.

Pokud implementujete vlastní složený ovládací prvek, který reaguje na vstupní události, zvažte použití událostí náhledu k potlačení a nahrazení vstupních událostí vyvolaných v dílčích podkomponentech událostí nejvyšší úrovně, která představuje kompletní ovládací prvek. Další informace najdete v tématu Označení směrovaných událostí jako popisovaných a zpracování tříd.

Další informace o vstupním systému WPF a způsobu interakce vstupů a událostí v typických scénářích aplikace najdete v tématu Přehled vstupu.

EventSetters a EventTriggers

Ve stylech značek můžete pomocí EventSetterpříkazu . Při zpracování XAML se odkazovaná obslužná rutina přidá do stylované instance. Můžete deklarovat EventSetter pouze trasovanou událost. V následujícím příkladu je metoda odkazované obslužné ApplyButtonStyle rutiny události implementována v kódu za kódem.

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="{x:Type Button}">
            <EventSetter Event="Click" Handler="ApplyButtonStyle"/>
        </Style>
    </StackPanel.Resources>
    <Button>Click me</Button>
    <Button Click="Button_Click">Click me</Button>
</StackPanel>

Je pravděpodobné, že Style uzel už obsahuje další informace o stylu, které se týkají ovládacích prvků zadaného typu, a že je EventSetter součástí těchto stylů, podporuje opakované použití kódu i na úrovni revize. Abstrahuje EventSetter také názvy metod pro obslužné rutiny mimo obecnou aplikaci a značky stránek.

Další specializovaná syntaxe, která kombinuje směrované události a animační funkce WPF je EventTrigger. Stejně jako u směrované EventSetterudálosti můžete deklarovat EventTrigger pouze trasovanou událost. EventTrigger Obvykle se deklaruje jako součást stylu, ale EventTrigger lze ji deklarovat na elementech na úrovni stránky jako součást Triggers kolekce nebo v objektu ControlTemplate. Umožňuje EventTrigger určit Storyboard , která se spustí vždy, když směrovaná událost dosáhne prvku ve své trase, která deklaruje pro danou EventTrigger událost. Výhodou pouhého EventTrigger zpracování události a její příčinou spuštění existujícího scénáře je, že EventTrigger poskytuje lepší kontrolu nad scénářem a jeho chováním za běhu. Další informace najdete v tématu Použití triggerů událostí k řízení scénáře po jeho spuštění.

Další informace o směrovaných událostech

Koncepty a pokyny v tomto článku můžete použít jako výchozí bod při vytváření vlastních směrovaných událostí ve vlastních třídách. Vlastní události můžete také podporovat pomocí specializovaných datových tříd událostí a delegátů. Vlastník směrované události může být libovolná třída, ale směrované události musí být vyvolány a zpracovány UIElement nebo ContentElement odvozené třídy, aby byly užitečné. Další informace o vlastních událostech najdete v tématu Vytvoření vlastní směrované události.

Viz také