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

Vývojáři aplikací WPF (Windows Presentation Foundation) 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í na více naslouchacích procesů ve stromu. Tyto funkce se nenašel 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.

Požadavky

Tento článek předpokládá základní znalosti modulu CLR (Common Language Runtime), objektově orientovaného programování a způsobu, jakým lze rozložení elementů WPF konceptualizovat jako strom. Pokud chcete postupovat podle příkladů v tomto článku, pomůže vám to, pokud 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 funkční perspektivy je směrovaná událost typem události, která může vyvolat obslužné rutiny na více naslouchacích procesů ve stromu elementů, nejen ve zdroji událostí. Naslouchací proces událostí je prvek, kde je připojena a vyvolána obslužná rutina události. Zdroj události je prvek nebo objekt, který původně vyvolal událost.

  • Z hlediska implementace je směrovaná událost událostí registrovaná 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 s "obálkou" 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 buď deklarovány v xaml, nebo vytvoření instance v kódu. Prvky aplikace existují ve stromu prvků. V závislosti na tom, jak je definovaná směrovaná událost, při vyvolání události na zdrojovém prvku:

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

Představte si 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 vykreslí, jak je znázorněno:

Strom elementu XAML se třemi tlačítky: Ano, Ne a Zrušit.

Každé ze tří tlačítek je potenciálním Click zdrojem událostí. Když kliknete na jedno z tlačítek, vyvolá Click událost, která se z tlačítka bublinuje 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í také Click připojené obslužné rutiny událostí. Click Když událost dosáhne elementuStackPanel, vyvolá systém událostí WPF obslužnou rutinuYesNoCancelButton_Click, která je k němu připojena. Trasa události události v příkladu Click je: Button ->StackPanel ->Border -> po sobě jdoucí nadřazené prvky.

Poznámka:

Prvek, 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 element, kde je obslužná rutina události připojena a vyvolána, a je identifikována 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é události a odlišily ho od typické události CLR:

  • Složení a zapouzdření ovládacích prvků: Různé ovládací prvky v WPF mají bohatou kon režim stanu l. Obrázek můžete například umístit do objektu Button, který efektivně rozšíří 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.

  • Body přílohy jedné obslužné rutiny: Pro každou událost tlačítka Click můžete zaregistrovat obslužnou rutinu, ale u směrovaných událostí 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 prvků pod obslužnou rutinou s jednotným číslem, jako je přidání nebo odebrání dalších tlačítek, aniž byste museli registrovat události 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 jakékoli 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ěhový odraz k identifikaci události.

Způsob 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 identicky pojmenovanou událost CLR "wrapper". Obálka událostí CLR obsahuje add a remove přistupující 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. remove A add přístupové objekty přepíší implementaci CLR a volají směrovanou událost AddHandler a RemoveHandler metody. Směrované zálohování událostí a mechanismus připojení se koncepčně podobá tomu, jak je vlastnost závislosti VLASTNOST CLR, která je podporována DependencyProperty třídou a registrována 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 do po sobě jdoucích nadřazených prvků a vyvolá jejich obslužné rutiny událostí postupně, dokud nedosáhne kořene stromu elementu. Většina směrovaných událostí používá strategii směrování bublání. Směrované události s bublinou se obvykle používají k hlášení 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 stromu elementu. Směrovaná událost pak směruje do po sobě jdoucích podřízených prvků a následně vyvolá jejich obslužné rutiny událostí, dokud nedosáhne zdroje událostí. Události, které následují po trase tunelování, se také označují jako události ve verzi Preview . Vstupní události WPF jsou obecně implementovány jako dvojice náhledu a bublání.

  • Direct: Vyvolá se pouze obslužné rutiny událostí ve zdroji událostí. Tato strategie nesměrování je podobná událostem architektury 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 mohou 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 starat se o to, že událost, kterou zpracováváte, se 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 elementu, 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 v rámci 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 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 jsou odvozeny od 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ěrovanou 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 v jakékoli instanci třídy naslouchacího procesu. 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 pro stránku XAML. Naslouchací proces událostí je prvek, kde je obslužná rutina události připojena a vyvolána.

Pro událost, která je členem (zděděno nebo jinak) 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 například StackPanel třída neimplementuje Click událost, pro připojení obslužné rutiny k StackPanel Click události, která bublinuje až do daného elementu, 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 musí odpovídat typu delegáta pro směrovanou událost. Parametr sender delegáta RoutedEventHandler Click události 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 kódu 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 to základní delegát směrované obslužné rutiny událostí, některé kontrolní nebo implementační scénáře vyžadují různé delegáty, kteří podporují specializovanější data událostí. Například pro DragEnter směrovanou událost by obslužná rutina měla implementovat delegáta DragEventHandler . Kód obslužné rutiny tak může 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 pro směrovanou událost 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ý StackPanel StackPanel1:

    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 pro standardní událost CLR. Většina existujících směrovaných událostí WPF implementuje obálku CLR, čímž se povolí syntaxe událostí specifická 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 jazyce 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 naleznete v tématu Visual Basic a WPF zpracování událostí.

Koncept zpracovaných

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 nechat jakoukoli obslužnou rutinu události podél trasy události označit směrovanou událost jako zpracována. Pokud chcete událost označit jako zpracová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álostí se obvykle pro danou 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ž instance nebo obslužné rutiny 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 může ovlivnit způsob návrhu Handled aplikace a kódu obslužných rutin událostí. Ke zpracování směrovaných událostí můžete konceptualizovat Handled jako jednoduchý protokol. 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 zpracována, naslouchací procesy dříve v trase události nemají obslužnou rutinu události nebo žádný z registrovaných obslužných rutin na událost neodpověděl způsobem, který by odů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:

    • Nic se neděje. Událost zůstává neošetřená a směruje na další naslouchací proces ve stromu.

    • Spusťte kód v reakci na událost, ale ne v rozsahu, který odůvodňuje označení události jako zpracovávané. Událost zůstává neošetřená a směruje 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ů nebude volat další obslužné rutiny. Výjimkou jsou naslouchací procesy s obslužnými rutinami, které byly speciálně zaregistrovány s nastavenou handledEventsToo na truehodnotu .

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

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

Obslužné rutiny tříd

Směrované obslužné rutiny událostí mohou být obslužné rutiny instance nebo obslužné rutiny třídy . 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 u jakékoli instance této třídy. Vzhledem k tomuto chování jsou směrované události označeny jako popisované, jsou často označeny jako takové v rámci obslužných rutin třídy. Existují dva typy obslužných rutin tříd:

  • Obslužné rutiny událostí statické třídy, které jsou registrovány voláním RegisterClassHandler metody v rámci konstruktoru statické třídy.
  • Přepsat obslužné rutiny událostí třídy, které jsou registrovány přepsáním metod virtuální události základní třídy. Metody virtuálních událostí základní třídy primárně existují pro vstupní události a mají názvy začínající na název> události On<a OnPreview<název> události.

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 zaregistrovat obslužnou rutinu nastavenou handledEventsToo na truehodnotu . Další informace o implementaci vlastních obslužných rutin tříd nebo práci s nežádoucím zpracováním tříd najdete v tématu Označení směrovaných událostí jako zpracovávaný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 v jiné třídě než element a vyvolat tuto událost u libovolného prvku ve stromu. K tomu je potřeba 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ý šíří prostřednictvím stromu 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 je název události 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. Můžete také připojit obslužné rutiny pro připojené události v kódu za voláním AddHandler metody na objektu, ke kterému by obslužná rutina měla být připojena.

Vstupní systém WPF používá připojené události značně. 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.MouseDown UIElement událost na události prostřednictvím ekvivalentní UIElement.MouseDown směrované události než pomocí připojené syntaxe událostí v XAML nebo kódu.

Další informace o připojenýchudálostch

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 elementy, 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ého prvku, aby bylo možné zpracovávat směrované události vyvolané na podřízených prvcích. Pokud nadřazený prvek nemá směrovanou událost jako člena, budete muset použít kvalifikovanou syntaxi názvu události. Příklad:

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

V příkladu je naslouchací proces nadřazeného elementu, 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 I když 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é UIElement nebo ContentElement 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 xmlnsoboru názvů XAML a mapování oboru názvů pro WPF XAML.

Vstupní události 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í trasu tunelování, název, který má předponu "Preview". Předpona náhledu označuje, že se událost náhledu dokončí před zahájením spárované bublinové události. Vstupní události často přicházejí ve dvojicích, přičemž jedna je událost náhledu a druhá událost směrovaná nasměrovaná. 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 verzi bublinové verze nebo pouze přímou směrovanou verzi. V dokumentaci k rozhraní API se směrovaná témata událostí křížově odkazují na dvojice směrovaných událostí a upřesňují strategii směrování pro každou směrovanou událost.

Vstupní události WPF, které přicházejí ve dvojicích, 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 bublinové 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 bublání událostí.

Vstupní událost náhledu, která je označená jako zpracována, nevyvolá žádné běžně zaregistrované obslužné rutiny událostí pro zbytek trasy preview a spárovaná bublinová 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 testech 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 bylo možné "nahradit" událostí specifickou pro řízení nejvyšší úrovně.

Abyste si ukázali, 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 jak PreviewMouseDown MouseDown spárovaných událostí, leaf element #2 tak i spárovaných událostí:

Diagram znázorňující tok směrování událostí z kořenového prvku do jiných prvků

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

  1. PreviewMouseDown událost tunelování v kořenovém elementu.
  2. PreviewMouseDown tunneling event on intermediate element #1.
  3. PreviewMouseDown tunneling event on leaf element #2, což je zdrojový prvek.
  4. MouseDown bublinová událost u elementu typu list č. 2, což je zdrojový prvek.
  5. MouseDown bublinová událost u přechodné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, kde byla obslužná rutina vyvolána. 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 každé směrované instance události se objekt, který vyvolal událost, nezmění, protože událost prochází stromem elementu sender , ale dělá to. V krocích 3 a 4 předchozího diagramu se jedná o Source sender 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 zpracovanou. Obvykle, jakmile je vstupní událost označena Handled, obslužné rutiny dále podél trasy události nejsou vyvolány. Obslužné rutiny vstupních událostí zaregistrované v handledEventsToo sadě true parametrů budou vyvolány 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í verze Preview a bublání, se sdílenými daty událostí a sekvenčním zvýšením události náhledu, pak bublající událost, platí pouze pro některé události vstupu WPF, a ne pro všechny směrované události. Pokud implementujete vlastní vstupní událost pro řešení pokročilého scénáře, zvažte použití přístupu 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 úplné řízení. Další informace naleznete v tématu Označení směrovaných událostí jako zpracovávaný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 naleznete v tématu Přehled vstupu.

EventSetters a EventTriggers

Ve stylech revizí můžete použít předem deklarovanou syntaxi zpracování událostí XAML pomocí příkazu EventSetter. 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 se v kódu implementuje odkazovaná metoda obslužné ApplyButtonStyle rutiny události.

<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 již obsahuje další informace o stylu, které se týkají ovládacích prvků zadaného typu a mají EventSetter být součástí těchto stylů, podporuje opětovné použití kódu i na úrovni značek. EventSetter Také abstrahuje názvy metod pro obslužné rutiny mimo obecnou aplikaci a značky stránky.

Další specializovaná syntaxe, která kombinuje směrované události a animační funkce WPF je EventTrigger. Stejně jako v případě EventSetter, můžete deklarovat EventTrigger pouze pro směrovanou událost. EventTrigger Obvykle je deklarována jako součást stylu, ale lze ji EventTrigger deklarovat na elementech na úrovni stránky jako součást Triggers kolekce nebo v ControlTemplatesouboru . Umožňuje EventTrigger určit Storyboard , která se spustí vždy, když směrovaná událost dosáhne prvku ve své trase, která deklaruje událost pro danou EventTrigger událost. Výhodou pouhého EventTrigger zpracování události a její příčinou spuštění existující 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é