官术网_书友最值得收藏!

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.

主站蜘蛛池模板: 灵山县| 和静县| 岑巩县| 厦门市| 京山县| 广丰县| 宜川县| 宁强县| 札达县| 习水县| 榕江县| 德清县| 平泉县| 昂仁县| 淳化县| 来凤县| 浑源县| 宿迁市| 阿拉善右旗| 邳州市| 太仆寺旗| 吉林市| 海南省| 湘潭县| 瓦房店市| 北宁市| 师宗县| 连城县| 华亭县| 万安县| 西宁市| 木兰县| 大田县| 韶关市| 福贡县| 汾阳市| 龙口市| 叙永县| 图木舒克市| 赤壁市| 和平县|