- Mastering Windows Presentation Foundation
- Sheridan Yuen
- 660字
- 2021-06-24 16:49:03
Handling events in Attached Properties
There is one way to handle events in WPF without having to resort to writing code in the code behind file of a View. Using Attached Properties, we can encapsulate the handling of events and effectively expose their behavior using properties that we can data bind to in our Views. Let's take a look at a simple example using the PreviewKeyDown event:
public static DependencyProperty OnEnterKeyDownProperty = DependencyProperty.RegisterAttached("OnEnterKeyDown", typeof(ICommand), typeof(TextBoxProperties), new PropertyMetadata(OnOnEnterKeyDownChanged)); public static ICommand GetOnEnterKeyDown(DependencyObject dependencyObject) { return (ICommand)dependencyObject.GetValue(OnEnterKeyDownProperty); } public static void SetOnEnterKeyDown(DependencyObject dependencyObject, ICommand value) { dependencyObject.SetValue(OnEnterKeyDownProperty, value); } private static void OnOnEnterKeyDownChanged( DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { TextBox textBox = (TextBox)dependencyObject; if (e.OldValue == null && e.NewValue != null) textBox.PreviewKeyDown += TextBox_OnEnterKeyDown; else if (e.OldValue != null && e.NewValue == null) textBox.PreviewKeyDown -= TextBox_OnEnterKeyDown; } private static void TextBox_OnEnterKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter || e.Key == Key.Return) { TextBox textBox = sender as TextBox; ICommand command = GetOnEnterKeyDown(textBox); if (command != null && command.CanExecute(textBox)) command.Execute(textBox); } }
As can be seen in this example, the event is handled by attaching an event handler in the normal way, except that all relating code is encapsulated within the class that declares the Attached Property. Let's take a closer look. First, we declare an Attached Property named OnEnterKeyDown of type ICommand in a class named TextBoxProperties, and we pass a reference of our handling method to the PropertyChangedCallback delegate parameter of the PropertyMetadata constructor.
The GetOnEnterKeyDown and SetOnEnterKeyDown methods represent the normal way to get and set Attached Property values. In the unfortunately named OnOnEnterKeyDownChanged method, which will be called when the property value changes, we look at the NewValue and OldValue values of the DependencyPropertyChangedEventArgs input parameter in order to decide whether we need to attach or detach the event handler to the PreviewKeyDown event of the relevant TextBox.
If the OldValue value is null and the NewValue value is not null, it means that there was no previous value, and so the property is being set for the first time. In this case, we want to attach the event handler. Conversely, when the OldValue value is not null and the NewValue value is null, it means that there previously was a value, which has been removed, so we should detach the event handler.
Finally, the TextBox_OnEnterKeyDown event handling method first detects whether either the Enter key or the Return key were pressed. If one was pressed, the data bound ICommand instance is checked for null and if the command can execute, it is then executed. Therefore, we have effectively wrapped a PreviewKeyDown event in an Attached Property and can now execute any command that has been data bound to it when the user presses Enter on their keyboard.
In order to use this Attached Property, we must first add a XAML namespace prefix for our Attached folder in the XAML file of the View that this functionality is required in. Note that the TextBoxProperties class will be declared in the Attached folder of the Views project and so, its namespace will be as follows:
xmlns:Attached="clr-namespace:CompanyName.ApplicationName.Views.Attached; assembly=CompanyName.ApplicationName.Views"
Microsoft's convention for naming these prefixes is for the first character to be a lowercase letter, but it has always made more sense to me to simply use the last segment of the declared namespace, which will start with a capital letter. Once you have defined the prefix, you can use the Attached Property, as shown in the following example:
<TextBox Attached:TextBoxProperties.OnEnterKeyDown="{Binding Command}" />
Any UI events that we might need to handle in our applications can be encapsulated in Attached Properties in this same way. At first, this might seem to be a complicated way to handle events, compared with having a simple handler in a code behind file, but once we have a collection of these properties declared, we will find ourselves having to create fewer and fewer new ones. Think of them as simply being a reusable way of converting events into properties.
- Getting Started with Gulp(Second Edition)
- Progressive Web Apps with React
- Visual FoxPro程序設計教程(第3版)
- Java Web及其框架技術
- Python高級機器學習
- 程序是怎樣跑起來的(第3版)
- Keras深度學習實戰
- R語言與網絡輿情處理
- Microsoft Dynamics AX 2012 R3 Financial Management
- QlikView Unlocked
- Monitoring Docker
- 程序員的英語
- Learning iOS Penetration Testing
- Learning Puppet
- 零基礎入門Python數據分析與機器學習