Archive

Posts Tagged ‘Dependency Properties’

ReSharper Code Snippet for Dependency Properties

January 17th, 2008

This is a ReSharper code snippet I’ve been using quite a lot lately – it allows you to easily create a WPF dependency property along with event handlers, documentation, and initialization code. Here’s a sample:

#region MyStringProperty dependency property

/// <summary>
/// This is a sample string property.
/// </summary>
public static readonly DependencyProperty MyStringPropertyProperty;

//TODO: copy to static constructor
//register dependency property
//FrameworkPropertyMetadata md = new FrameworkPropertyMetadata("hello world", MyStringPropertyPropertyChanged);
//MyStringPropertyProperty = DependencyProperty.Register("MyStringProperty", typeof (string), typeof (MyControl), md);                                                      


/// <summary>
/// A property wrapper for the <see cref="MyStringPropertyProperty"/>
/// dependency property:<br/>
/// This is a sample string property.
/// </summary>
public string MyStringProperty
{
  get { return (string) GetValue(MyStringPropertyProperty); }
  set { SetValue(MyStringPropertyProperty, value); }
}


/// <summary>
/// Handles changes on the <see cref="MyStringPropertyProperty"/> dependency property. As
/// WPF internally uses the dependency property system and bypasses the
/// <see cref="MyStringProperty"/> property wrapper, updates should be handled here.
/// </summary>
/// <param name="d">The currently processed owner of the property.</param>
/// <param name="e">Provides information about the updated property.</param>
private static void MyStringPropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  MyControl owner = (MyControl) d;
  string newValue = (string) e.NewValue;

  //TODO provide implementation
  throw new NotImplementedException("Change event handler for dependency property MyStringProperty not implemented.");
}

#endregion

Just import the attached snippet into ReSharper, then type dpp in Visual Studio to trigger the template.

BTW: If you’re using VS without ReSharper but need snippets for dependency properties, routed events or routed commands, Dr. WPF has the cure.

Download File: dpp-snippet.xml

Explicitly update binding sources

January 16th, 2008

In WPF data binding scenarios, the binding source is usually updated implicitly – if you, for example, edit the text of a bound TextBox control, the underlying binding source is updated a soon as the control loses focus.

This is something you might want to prevent sometimes – a common scenario is a model dialog that provides a Cancel button to abort changes. The basic idea is that the underlying data remains unchanged until you commit all your changes at once if the dialog’s OK button is clicked.

The solution to prevent automatic updates of the binding source is to set the UpdateSourceTrigger property to Explicit, which prevents automatic updates of the underlying data item:

<TextBox Text="{Binding Path=Name, UpdateSourceTrigger=Explicit}" />

However, this feature comes with a catch: You’ll have to trigger updates on all your controls manually. Beatriz Costa posted a generic solution, but I found it a bit tedious to explicitly update every single control on my dialog. As a result, I came up with a solution that recursively processes a visual tree from a given starting point and updates all controls that provide one or several bindings of your choice:

/// <summary>
/// Recursively processes a given dependency object and all its
/// children, and updates sources of all objects that use a
/// binding expression on a given property.
/// </summary>
/// <param name="obj">The dependency object that marks a starting
/// point. This could be a dialog window or a panel control that
/// hosts bound controls.</param>
/// <param name="properties">The properties to be updated if
/// <paramref name="obj"/> or one of its childs provide it along
/// with a binding expression.</param>
public static void UpdateBindingSources(DependencyObject obj,
                          params DependencyProperty[] properties)
{
  foreach (DependencyProperty depProperty in properties)
  {
    //check whether the submitted object provides a bound property
    //that matches the property parameters
    BindingExpression be =
      BindingOperations.GetBindingExpression(obj, depProperty);
    if (be != null) be.UpdateSource();
  }

  int count = VisualTreeHelper.GetChildrenCount(obj);
  for(int i=0; i<count; i++)
  {
    //process child items recursively
    DependencyObject childObject = VisualTreeHelper.GetChild(obj, i);
    UpdateBindingSources(childObject, properties);
  }
}

Using the above method is quite simple: Just set a starting point (window, grid, whatever) along with an arbitrary number of dependency properties you’d like to have processed. As an example: The snipped below commits all bound Text properties of a dialog’s TextBox controls as well bound items of XamComboEditor dropdown controls:

//update TextBox and ComboBox controls of the dialog
DependencyProperty dpText = TextBox.TextProperty;
DependencyProperty dpSelectedItem = XamComboEditor.SelectedItemProperty;
UpdateBindingSources(this, dpText, dpSelectedItem);
Author: Categories: WPF Tags: , ,