Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
swdev:dotnet:wpf:dependency_properties [2010/12/27 14:56]
smayr created
swdev:dotnet:wpf:dependency_properties [2013/01/25 09:16] (current)
smayr [Example 1]
Line 1: Line 1:
 == Dependency Properties == == Dependency Properties ==
  
-If data binding to certain properties is required, then these need to be implemented as Dependency Properties. +If data binding is required to certain properties, then these need to be implemented as Dependency Properties. 
  
 Here is a good example (from: [[http://csharpsimplified.wordpress.com/2008/12/26/dependency-property|C# is Easy: Dependency Property]]): Here is a good example (from: [[http://csharpsimplified.wordpress.com/2008/12/26/dependency-property|C# is Easy: Dependency Property]]):
Line 8: Line 8:
 public class Button : ButtonBase public class Button : ButtonBase
 { {
-// The dependency property +  // The dependency property 
-public static readonly DependencyProperty IsCancelProperty; +  public static readonly DependencyProperty IsCancelProperty; 
-static Button()+   
 +  // Constructor 
 +  static Button() 
 +  { 
 +    // Register the property 
 +    Button.IsCancelProperty = DependencyProperty.Register(“IsCancel”, 
 +        typeof(bool), typeof(Button), 
 +        new FrameworkPropertyMetadata(false, 
 +        new PropertyChangedCallback(OnIsCancelPropertyChanged))); 
 +    … 
 +  } 
 +   
 +  // A .NET property wrapper (not must) 
 +  public bool IsCancel 
 +  { 
 +    get { return (bool)GetValue(Button.IsCancelProperty ); } 
 +    set { SetValue(Button.IsCancelProperty , value); } 
 +  } 
 +   
 +  // A property changed callback (not must) 
 +  private static void OnIsCancelPropertyChanged( 
 +    DependencyObject o, DependencyPropertyChangedEventArgs e) { … } 
 +  … 
 +
 +</code> 
 + 
 +Alternatively: 
 +<code csharp> 
 +public class Button : ButtonBase
 { {
-// Register the property +  // The dependency property declaration, and registration 
-Button.IsCancelProperty = DependencyProperty.Register(“IsCancel”, +  public static readonly DependencyProperty IsCancelProperty = DependencyProperty.Register(“IsCancel”, 
-typeof(bool), typeof(Button), +        typeof(bool), typeof(Button), 
-new FrameworkPropertyMetadata(false, +        new FrameworkPropertyMetadata(false, 
-new PropertyChangedCallback(OnIsDefaultChanged))); +        new PropertyChangedCallback(OnIsCancelPropertyChanged))); 
-+         
 +  // A .NET property wrapper (not must) 
 +  public bool IsCancel 
 +  { 
 +    get { return (bool)GetValue(Button.IsCancelProperty ); } 
 +    set { SetValue(Button.IsCancelProperty , value); } 
 +  } 
 +   
 +  // A property changed callback (not must) 
 +  private static void OnIsCancelPropertyChanged( 
 +    DependencyObject source, DependencyPropertyChangedEventArgs e)  
 +  { 
 +       Button control = source as Button; 
 +  
 +       // Put some update logic here... 
 +       control.IsCancel = (bool)e.NewValue; 
 +       if (control.IsCancel == true) 
 +       { 
 +           // do something 
 +       }  
 +  } 
 +   
 +  // Constructor 
 +  static Button() 
 +  { 
 +  } 
 +   
 +  
 } }
-// A .NET property wrapper (not must) +</code>
-public bool IsCancel+
  
 +IMPORTANT: The accessor property is fine to use, but the XAML code will only call the SetValue() and GetValue() methods directly, so make sure that no other code gets added to the accessor property, to make sure both work the same.
 +
 +=== Example 1 ===
 +<code csharp>
 +public class Employee : DependencyObject
 { {
-get { return (bool)GetValue(Button.IsCancelProperty ); } +    private static readonly DependencyProperty EmpIdProperty = 
-set { SetValue(Button.IsCancelProperty , value); } +        DependencyProperty.Register("EmpId", typeof(int), typeof(Employee), 
-+        new PropertyMetadata(0, 
-// A property changed callback (not must+            new PropertyChangedCallback(EmpIdCallBack), 
-private static void OnIsCancelChanged+            new CoerceValueCallback(CoerceEmpId))); 
-DependencyObject oDependencyPropertyChangedEventArgs e) { … + 
-+    private static readonly DependencyProperty NameProperty = 
 +        DependencyProperty.Register("Name", typeof(string), typeof(Employee)); 
 + 
 +    private static readonly DependencyProperty DepartmentProperty = 
 +        DependencyProperty.Register("Department", typeof(string), typeof(Employee)); 
 + 
 +    private static readonly DependencyProperty CompanyProperty = 
 +        DependencyProperty.Register("Company", typeof(string), typeof(Employee), 
 +        new PropertyMetadata("WPF In Corp")); 
 + 
 +    // If employee id is greater than 1000 then make it 1000 
 +    static void EmpIdCallBack(DependencyObject d, DependencyPropertyChangedEventArgs args) 
 +    { 
 +        Employee emp = (Employee)d; 
 + 
 +        if (emp.EmpId >= 1000) 
 +        { 
 +            emp.EmpId = 1000; 
 +        } 
 +    } 
 + 
 +    // If the employee Id is negative then make it positive 
 +    static Object CoerceEmpId(DependencyObject d, Object baseValue) 
 +    { 
 +        int value = (int)baseValue; 
 + 
 +        if (value < 0) 
 +            return value * -1; 
 +        else 
 +            return value; 
 +    } 
 + 
 +    public int EmpId 
 +    { 
 +        get { return (int)GetValue(EmpIdProperty); } 
 +        set { SetValue(EmpIdProperty, value); } 
 +    
 + 
 +    public string Name 
 +    { 
 +        get { return (string)GetValue(NameProperty); } 
 +        set { SetValue(NameProperty, value); } 
 +    } 
 + 
 +    public string Department 
 +    { 
 +        get { return (string)GetValue(DepartmentProperty);
 +        set { SetValue(DepartmentPropertyvalue); } 
 +    } 
 + 
 +    public string Company 
 +    { 
 +        get { return (string)GetValue(CompanyProperty); 
 +        set { SetValue(CompanyProperty, value); } 
 +    }
 } }
 </code> </code>
 +
 +Source: [[http://zamjad.wordpress.com/2009/07/13/dependency-property-metadata|Zeeshan Amjad: Dependency Property Metadata]]
 +
 +=== Example 2 ===
 +
 +A user control that requires a Dependency Property in order to set the ''SelectedIndex'' in a ''ListBox'' using Data Binding.
 +
 +XAML:
 +<code xml>
 +<UserControl x:Class="ACME.Controls.ucActiveInstrument". . .>
 +. . .
 +<Grid>
 +        <ListBox Name="lstOptions" Width="110" Height="40" SelectedIndex="1"
 +                 SelectionChanged="lstOptions_SelectionChanged">
 +            <ListBoxItem>
 +                <ListBoxItem.Content>
 +                    <Image Source="/images/icons/icon-device-right.png" Height="25" />
 +                </ListBoxItem.Content>
 +            </ListBoxItem>
 +            <ListBoxItem>
 +                <ListBoxItem.Content>
 +                    <Image Source="/images/icons/icon-device-both.png" Height="25" />
 +                </ListBoxItem.Content>
 +            </ListBoxItem>
 +            <ListBoxItem>
 +                <ListBoxItem.Content>
 +                    <Image Source="/images/icons/icon-device-left.png" Height="25" />
 +                </ListBoxItem.Content>
 +            </ListBoxItem>
 +        </ListBox>
 +    </Grid>
 +</UserControl>
 +</code>
 +
 +C# code:
 +<code csharp>
 +using System;
 +using System.Collections.Generic;
 +using System.Linq;
 +using System.Text;
 +using System.Windows;
 +using System.Windows.Controls;
 +using System.Windows.Data;
 +using System.Windows.Documents;
 +using System.Windows.Input;
 +using System.Windows.Media;
 +using System.Windows.Media.Imaging;
 +using System.Windows.Navigation;
 +using System.Windows.Shapes;
 +
 +namespace ACME.Controls
 +{
 +    public partial class ucActiveInstrument : UserControl
 +    {
 +        #region DependencyProperty SelectedItemIndex
 +        //-----------------------------------
 +        // SelectedItemIndex
 +        //-----------------------------------
 +        // Dependency Property
 +        public static readonly DependencyProperty SelectedItemIndexProperty =
 +          DependencyProperty.Register(
 +              "SelectedItemIndex",
 +              typeof(int),
 +              typeof(ucActiveInstrument),
 +              new FrameworkPropertyMetadata(
 +                    new int(),
 +                    OnSelectedItemIndexPropertyChanged
 +              )
 +          );
 +
 +        // .NET Property Wrapper
 +        public int SelectedItemIndex
 +        {
 +            // Important: Do not add any logic to these properties, because they are only 
 +            // called when you set the property from code. If you set the property from XAML 
 +            // the SetValue() method is called directly.
 +            get { return (int)GetValue(SelectedItemIndexProperty); }
 +            set { SetValue(SelectedItemIndexProperty, value); }
 +        }
 +        // Alias
 +        public int SelectedItemIdx
 +        {
 +            get { return SelectedItemIndex; }
 +        }
 +
 +        ///----------------------------------------------------------------------------------------
 +        /// <summary>
 +        /// OnPropertyChanged event handler for fitting view model.
 +        /// </summary>
 +        /// <param name="source">Source control</param>
 +        /// <param name="e">Event Arguments</param>
 +        ///----------------------------------------------------------------------------------------
 +        private static void OnSelectedItemIndexPropertyChanged(
 +          DependencyObject source,
 +          DependencyPropertyChangedEventArgs e)
 +        {
 +            ucActiveInstrument control = source as ucActiveInstrument;
 +            //DateTime time = (DateTime)e.NewValue;
 +
 +            //-----------------------------------------
 +            // Put some update logic here...
 +            //-----------------------------------------
 +            //SetDataBinding((TFittingViewModel)e.NewValue, control);
 +            //SetBinauralView(control);
 +            control.lstOptions.SelectedIndex = (int)e.NewValue;
 +        }
 +        #endregion
 +
 +        //-----------------------------------------------------------------------------------------
 +        /// <summary>
 +        /// Constructor.
 +        /// </summary>
 +        //-----------------------------------------------------------------------------------------
 +        public ucActiveInstrument()
 +        {
 +            InitializeComponent();
 +        }
 +
 +        //-----------------------------------------------------------------------------------------
 +        /// <summary>
 +        /// SelectionChange event handler for lstOptions.
 +        /// </summary>
 +        /// <param name="sender"></param>
 +        /// <param name="e"></param>
 +        //-----------------------------------------------------------------------------------------
 +        private void lstOptions_SelectionChanged(object sender, SelectionChangedEventArgs e)
 +        {
 +            this.SelectedItemIndex = lstOptions.SelectedIndex;
 +        }
 +
 +    }
 +}
 +</code>        
 +== See Also ==
 +  * [[swdev:dotnet:wpf:implementing_mvvm|Implementing M-V-VM]]
 +  * [[http://zamjad.wordpress.com/2009/07/13/dependency-property-metadata/|Zeeshan Amjad: Dependency Property Metadata]]