Ve WPF lze vytvořit attached události - Attached Events, někdy také nazývané Custom routed events. Ty nám obdobně jako Attached Dependency Properties, umožňují k libovolnému UIElementu přidat vlastní v tomto případě událost, kterou můžeme na elementu vyvolávat a odchytávat. Ve WPF se toto provádí pomoci třídy EventManager, kterou lze jako attached události registrovat přímo RoutedEvent.
V Silverlightu bohužel attached události nejsou implementované, viz msdn:
“Silverlight does not support creating a custom routed event. The only routed events available in Silverlight are the ones that are defined by existing Silverlight classes, as listed in the "Routed Events" section of Events Overview for Silverlight.” (viz. také Routed Events in Silverlight)
Každý toto obchází různými způsoby, které se snaží napodobit třídy z WPF.
Tak například v Silverlight Toolkit jsou události pro Drag & Drop (viz článek Drag Drop v Silverlight) implementovaný pomoci Dependency Properties. Řešení je ovšem interní v knihovně System.Windows.Controls.Toolkit.dll a nelze tedy třídy ExtendedRoutedEvent, ExtendedRoutedEventArgs a UIElementExtendedRoutedEventExtensions využít pro vlastní události. Obdobně Telerik ve svých RadControls for Silverlight mají implementované vlastní EventManager a RoutedEvent pro jejich kontroly.
Jediné obecné řešení (kromě vlastních implementací, například zde), které se mi podařilo najít, je codeplex projekt RoutedEvents implementation for Silverlight 3 including WPF compatability na adrese http://sl3routedevents.codeplex.com. Projekt obsahuje pouze jedinou Alpha verzi, a již se nijak dále nerozvíjí, nicméně lze jej použít. Výhodou řešení je jednoduchost použití, jak je vidět na následujícím příkladu:
Registrace attached události
public static class RefreshManager
{
public delegate void RefreshEventHandler(object sender, RoutedEventArgsEx e);
public static readonly RoutedEventEx RefreshEvent = EventManagerEx.RegisterRoutedEvent("Refresh", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(RefreshManager));
}
Vyvolání události
element.RaiseEventEx(new RoutedEventArgsEx(RefreshManager.RefreshEvent)); //(Event can "Bubble" to parent)
Registrace události
Událost bohužel nemůžeme registrovat přímo v XAML jako například takto ve WPF
<Grid x:Name="LayoutRoot" local:RefreshManager.Refresh="LayoutRoot_Refresh",
ale musíme pouze z kód behind:
using System;
using IdentityMine.Windows.Eventing;
namespace SilverlightAttachedEvents
{
public partial class MainPage : System.Windows.Controls.UserControl
{
public MainPage()
{
InitializeComponent();
LayoutRoot.AddHandlerEx(RefreshManager.RefreshEvent, new RefreshManager.RefreshEventHandler(LayoutRoot_Refresh), false);
}
private void LayoutRoot_Refresh(object sender, RoutedEventArgsEx e)
{
...
}
}
}