Non è raro non trovare tutte le caratteristiche di cui si ha bisogno nei controlli di Windows Presentation Foundation, seppure molto elastici e versatili tramite style e template. Nelle WinForm per personalizzare un controllo è necessario utilizzare subclassing o ereditare dal controllo per sovrascrivere alcuni metodi e anche questo è possibile farlo in WPF. In aiuto però possono venire anche le attached property che possono essere sfruttare per agganciare una proprietà ad un controllo ed influire su di esso basandosi su eventi e ulteriori proprietà. Il vantaggio di questo è approccio sta nel poter agganciare alcuni comportamenti a piacimento, anche su tipologie diverse di controlli; in questo caso queste proprietà prendono il nome di attached behavior.
In questo script si prepara quindi un behavior che permetta di nascondere automaticamente un Menu alla perdita del focus, come alcuni player fanno, e di farlo ricomparire alla pressione del tasto alt. Per farlo occorre creare una classe che contenga l'attached property con i rispettivi metodi statici Set e Get, come il pattern richiede per essere interpretato dal parser XAML.
public static class MenuBehavior { public static readonly DependencyProperty AutoHideProperty = DependencyProperty.RegisterAttached("AutoHide", typeof(Boolean), typeof(Menu), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnAutoHideChanged))); public static void SetAutoHide(Menu menu, bool value) { menu.SetValue(AutoHideProperty, value); } public static bool GetAutoHide(Menu menu) { return (bool)menu.GetValue(AutoHideProperty); }
Il metodo OnAutoHideChanged è il cuore del behavior, perché in esso va implementato il codice di personalizzazione. Nell'esempio in questione si deve intercettare la perdita del focus da parte del Menu per nasconderlo, e la pressione del tasto alt, a livello di oggetto radice (solitamente la Window), per farlo ricomparire.
private static void OnAutoHideChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Menu menu = (Menu)d; // Cerco l'elemento principale, per intercettare la pressione di tutti i pulsanti FrameworkElement parent = menu; while (true) { FrameworkElement newParent = LogicalTreeHelper.GetParent(parent) as FrameworkElement; if (newParent != null) parent = newParent; else break; } KeyEventHandler menuKeyDownHandler = delegate(object sender, KeyEventArgs ke) { // Se preme ALT, mostro il menu if (ke.KeyboardDevice.Modifiers == ModifierKeys.Alt) { menu.Visibility = Visibility.Visible; } }; if ((bool)e.NewValue) { // Intercetto gli eventi if (parent != null) parent.KeyDown += menuKeyDownHandler; menu.LostKeyboardFocus += MenuLostFocusHandler; menu.Visibility = Visibility.Collapsed; } else { // Non intercetto più gli eventi if (parent != null) parent.KeyDown -= menuKeyDownHandler; menu.LostKeyboardFocus -= MenuLostFocusHandler; menu.Visibility = Visibility.Visible; } }
A questo punto il suo utilizzo è piuttosto banale:
<Window xmlns:m="clr-namespace:MyApplicaation"> <DockPanel> <Menu DockPanel.Dock="Top" m:MenuBehavior.AutoHide="True"> <MenuItem Header="_File"> <MenuItem Header="_Exit" /> </MenuItem> </Menu> <TextBox></TextBox> </DockPanel> </Window>
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
I più letti di oggi
- Arriva WinFX beta2, WinFS beta2 a metà giugno
- Microsoft cambia nome a WinFX: ritorna .NET Framework 3.0
- Anche il .NET Framework 3.0 è in RC1
- #IE10 disponibile al download da subito: http://aspitalia.com/vf http://aspitalia.com/mix-11 #mix11
- #ie10 supporta il multitouch anche in #Javascript. http://aspitalia.com/build-win8 #BldWin
- il team del #windows store spiega in dettaglio come aggiungere applicazioni desktop allo store di #win8 https://aspit.co/95
- non perdete a #aspilive @CristianCivera su sviluppare app cross platform con #vs2013 e #xamarin: https://aspit.co/VS14-live #ios #android
- rilasciato l'sdk per il #microsoftband. supporto per app su #wp81 e #android: https://aspit.co/a2m
- finiamo con @itsonlyGianca e #Windows10 iot core e #raspberrypi2 con #VS2015 su #aspilive: https://aspit.co/VS2015-live
- oggi dalle 17:30 c'è il lancio online di @VisualStudio 2015. seguitelo live qui: https://aspit.co/a51 #vs2015