Přehled připojených událostí (WPF .NET)
Jazyk XAML (Extensible Application Markup Language) definuje komponentu jazyka a typ události označovanou 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.
Požadavky
Tento článek předpokládá základní znalost směrovaných událostí windows Presentation Foundation (WPF) a že jste si přečetli přehled směrovaných událostí a XAML ve WPF. Pokud chcete postupovat podle příkladů v tomto článku, pomůže vám to, pokud znáte XAML a víte, jak psát aplikace WPF.
Syntaxe připojených událostí
V syntaxi XAML je připojená událost určena názvem události a jeho 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.
Následující syntaxe atributu XAML připojí AquariumFilter_Clean
obslužnou rutinu AquariumFilter.Clean
připojené události k elementu aquarium1
:
<aqua:Aquarium x:Name="aquarium1" Height="300" Width="400" aqua:AquariumFilter.Clean="AquariumFilter_Clean"/>
V tomto příkladu je předpona aqua:
nezbytná, protože AquariumFilter
třídy Aquarium
existují v jiném oboru názvů a sestavení CLR (Common Language Runtime).
Můžete také připojit obslužné rutiny pro připojené události v kódu za sebou. Uděláte to tak, že zavoláte metodu AddHandler objektu, ke kterému by obslužná rutina měla připojit a předat identifikátor události a obslužnou rutinu jako parametry metody.
Jak WPF implementuje připojené události
Připojené události WPF se implementují jako směrované události zálohované polem RoutedEvent . V důsledku toho se připojené události šíří prostřednictvím stromu prvků po jejich vyvolání. Obecně platí, že objekt, který vyvolá připojenou událost, označovaný jako zdroj události, je systém nebo zdroj služby. Systémové zdroje nebo zdroje služeb nejsou přímou součástí stromu prvků. U jiných připojených událostí může být zdrojem událostí prvek ve stromu, například komponenta v rámci složeného ovládacího prvku.
Připojené scénáře událostí
Ve WPF se připojené události používají v určitých oblastech funkcí, kde je abstrakce na úrovni služby. WpF například používá připojené události povolené statickými Mouse nebo Validation třídami. Třídy, které komunikují se službou nebo ji používají, můžou interagovat s událostí pomocí syntaxe připojených událostí nebo zobrazit připojenou událost jako směrovanou událost. Druhá možnost je součástí toho, jak může třída integrovat možnosti služby.
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ů. Každá směrovaná vstupní událost je členem třídy základního elementu a je zajištěna událostí CLR "wrapper". 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.
Připojené události slouží k účelu architektury tím, že umožní budoucí rozšíření vstupních zařízení. Například nové vstupní zařízení by bylo potřeba zvýšit pouze pro Mouse.MouseDown
simulaci vstupu myši a nemuselo by od Mouse
něj odvozovat. Tento scénář zahrnuje zpracování kódu události, protože zpracování XAML připojené události by nebylo relevantní.
Zpracování připojené události
Proces kódování a zpracování připojené události je v podstatě stejný jako u ne připojené směrované události.
Jak jsme si poznamenali dříve, existující připojené události WPF obvykle nejsou určeny k přímému zpracování ve WPF. Častěji je účelem připojené události povolit prvek v rámci složeného ovládacího prvku, aby hlásil svůj stav nadřazeného prvku v rámci ovládacího prvku. V tomto scénáři je událost vyvolána v kódu a spoléhá na zpracování tříd v příslušné nadřazené třídě. Očekává se například, že položky v rámci objektu Selector mají vyvolat připojenou Selected událost, což je pak třída zpracována Selector
třídou. Třída Selector
potenciálně převede Selected
událost na SelectionChanged směrovanou událost. Další informace o směrovaných událostech a zpracování tříd naleznete v tématu Označení směrovaných událostí jako zpracovávaných a zpracování tříd.
Definování vlastní připojené události
Pokud vycházíte z běžných základních tříd WPF, můžete implementovat vlastní připojenou událost zahrnutím dvou metod příslušenství ve vaší třídě. Tyto metody jsou:
Metoda Add<event name>Handler s prvním parametrem, který je prvkem, na kterém je připojena obslužná rutina události, a druhý parametr, který je obslužnou rutinou události přidat. Metoda musí být
public
astatic
, bez návratové hodnoty. Metoda volá metodu AddHandler základní třídy, která předává směrovanou událost a obslužnou rutinu jako argumenty. Tato metoda podporuje syntaxi atributu XAML pro připojení obslužné rutiny události k elementu. Tato metoda také umožňuje přístup kódu k úložišti obslužných rutin událostí pro připojenou událost.Metoda Remove<event name>Handler s prvním parametrem, který je element, na kterém je připojena obslužná rutina události, a druhý parametr, který je obslužnou rutinou události odebrat. Metoda musí být
public
astatic
, bez návratové hodnoty. Metoda volá metodu RemoveHandler základní třídy, která předává směrovanou událost a obslužnou rutinu jako argumenty. Tato metoda umožňuje přístup kódu k úložišti obslužných rutin událostí pro připojenou událost.
WPF implementuje připojené události jako směrované události, protože identifikátor události RoutedEvent je definován systémem událostí WPF. Směrování události je také přirozeným rozšířením konceptu na úrovni jazyka XAML připojené události. Tato strategie implementace omezuje zpracování připojených událostí na UIElement odvozené třídy nebo ContentElement odvozené třídy, protože pouze tyto třídy mají AddHandler implementace.
Například následující kód definuje připojenou událost třídy Clean
AquariumFilter
owner, což není třída elementu. Kód definuje připojenou událost jako směrovanou událost a implementuje požadované metody přístupového objektu.
public class AquariumFilter
{
// Register a custom routed event using the bubble routing strategy.
public static readonly RoutedEvent CleanEvent = EventManager.RegisterRoutedEvent(
"Clean", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));
// Provide an add handler accessor method for the Clean event.
public static void AddCleanHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
{
if (dependencyObject is not UIElement uiElement)
return;
uiElement.AddHandler(CleanEvent, handler);
}
// Provide a remove handler accessor method for the Clean event.
public static void RemoveCleanHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
{
if (dependencyObject is not UIElement uiElement)
return;
uiElement.RemoveHandler(CleanEvent, handler);
}
}
Public Class AquariumFilter
' Register a custom routed event using the bubble routing strategy.
Public Shared ReadOnly CleanEvent As RoutedEvent = EventManager.RegisterRoutedEvent(
"Clean", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
' Provide an add handler accessor method for the Clean event.
Public Shared Sub AddCleanHandler(dependencyObject As DependencyObject, handler As RoutedEventHandler)
Dim uiElement As UIElement = TryCast(dependencyObject, UIElement)
If uiElement IsNot Nothing Then
uiElement.[AddHandler](CleanEvent, handler)
End If
End Sub
' Provide a remove handler accessor method for the Clean event.
Public Shared Sub RemoveCleanHandler(dependencyObject As DependencyObject, handler As RoutedEventHandler)
Dim uiElement As UIElement = TryCast(dependencyObject, UIElement)
If uiElement IsNot Nothing Then
uiElement.[RemoveHandler](CleanEvent, handler)
End If
End Sub
End Class
Metoda RegisterRoutedEvent , která vrací připojený identifikátor události je stejná metoda, která slouží k registraci ne připojených směrovaných událostí. Připojené i ne připojené směrované události se registrují do centralizovaného interního úložiště. Tato implementace úložiště událostí umožňuje koncept "události jako rozhraní", který je popsán v přehledu směrovaných událostí.
Na rozdíl od události CLR "wrapper" použité k zpět nepřiřazované směrované události lze připojené metody přístupového objektu událostí implementovat ve třídách, které nejsou odvozeny nebo UIElement ContentElement. To je možné, protože připojený kód backing události volá UIElement.AddHandler a UIElement.RemoveHandler metody na předané instanci UIElement
. Naproti tomu obálka CLR pro ne připojené směrované události volá tyto metody přímo ve vlastní třídě, takže třída musí být odvozena z UIElement
.
Vyvolání připojené události WPF
Proces vyvolání připojené události je v podstatě stejný jako u ne připojené směrované události.
Kód obvykle nebude muset vyvolat žádné existující připojené události WPF definované, protože tyto události se řídí obecným koncepčním modelem "služby". V tomto modelu jsou třídy služeb, například InputManager, zodpovědné za vyvolání připojených událostí definovaných WPF.
Při definování vlastní připojené události pomocí modelu WPF založit připojené události na směrovaných událostech, použijte metodu UIElement.RaiseEvent k vyvolání připojené události na libovolné UIElement nebo ContentElement. Při vyvolání směrované události, ať už je připojená nebo ne, je nutné určit prvek ve stromu elementu jako zdroj události. Tento zdroj se pak nahlásí jako RaiseEvent
volající. Například pro vyvolání AquariumFilter.Clean
připojené směrované události na aquarium1
:
aquarium1.RaiseEvent(new RoutedEventArgs(AquariumFilter.CleanEvent));
aquarium1.[RaiseEvent](New RoutedEventArgs(AquariumFilter.CleanEvent))
V předchozím příkladu aquarium1
je zdrojem událostí.
Viz také
.NET Desktop feedback