views:

58

answers:

3

In the book Visual C# 2010 Recipes: A Problem-Solution Approach, there is an example demonstrating the power of Dependency Properties. The example describes a UserControl that has two properties TextFontWeight and TextContent that have the dependency properties TextFontWeightProperty and TextContentProperty attached to them respectively.

The code behind the XAML goes as follows

    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 TestWpfApplication
{
    /// <summary>
    /// Interaction logic for TestDpControl.xaml
    /// </summary>
    public partial class TestDpControl : UserControl
    {
        public TestDpControl()
        {
            InitializeComponent();
            DataContext = this;
        }

        public FontWeight TextFontWeight
        {
            get { return (FontWeight)GetValue(TextFontWeightProperty); }
            set { SetValue(TextFontWeightProperty, value); }

        }

        public string TextContent
        {
            get { return (string)GetValue(TextContentProperty); }
            set { SetValue(TextContentProperty, value); }


        }

        public static readonly DependencyProperty TextContentProperty =
            DependencyProperty.Register(
            "TextContent",
            typeof(string),
            typeof(TestDpControl),

            new FrameworkPropertyMetadata(
                "Default Value",
                FrameworkPropertyMetadataOptions.AffectsArrange
                & FrameworkPropertyMetadataOptions.AffectsMeasure
                & FrameworkPropertyMetadataOptions.AffectsRender));


        public static readonly DependencyProperty TextFontWeightProperty =
            DependencyProperty.Register(
            "TextFontWeight",
            typeof(FontWeight),
            typeof(TestDpControl),
            new FrameworkPropertyMetadata(FontWeights.Normal,
                FrameworkPropertyMetadataOptions.AffectsArrange
                & FrameworkPropertyMetadataOptions.AffectsMeasure
                & FrameworkPropertyMetadataOptions.AffectsRender,
                TextFontWeight_PropertyChanged,
                TextFontWeight_CoerceValue));

        private static object TextFontWeight_CoerceValue(DependencyObject d, object value)
        {
            FontWeight fontWeight = (FontWeight)value;
            if (fontWeight == FontWeights.Bold || fontWeight == FontWeights.Normal)
            {
                return fontWeight;
            }
            return FontWeights.Normal;

        }

        private static void TextFontWeight_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TestDpControl myControl = d as TestDpControl;

            if (myControl != null)
            {
                FontWeight fontWeight = (FontWeight)e.NewValue;
                string fontWeightName;

                if (fontWeight == FontWeights.Bold)
                    fontWeightName = "Bold";
                else
                    fontWeightName = "Normal";
                myControl.txblFontWeight.Text = string.Format("Font weight set to:{0}.", fontWeightName);

            }


        }
    }}

I am having trouble understanding what benefit does the Dependency Property provides in this scenario. Wouldn't a simple getter returning the FontWeights.Bold for the TextFontWeight and "Default Value" for TextContent suffice in this situation? It would be great if somebody could illustrate the power of Dependency Property in this particular example or whether its usage is prudent in this scenario.

Thanks

+2  A: 

One advantage to using DependencyProperties is that it makes it easy to bind these properties in XAML (data binding being one of the most powerful aspects of WPF IMHO).

Here is a good writeup on some of the additional power of dependency properties:

http://joshsmithonwpf.wordpress.com/2007/05/16/demystifying-dependency-properties/

Note that you can still bind to normal properties in XAML, but in some cases you'll have to implement INotifyPropertyChanged to keep the UI in sync.

RQDQ
+1  A: 

Since the example in your book is very basic, you are right, that a simple setter/getter would maybe enough to fit this particular scenario. But if you would like to use the control in general cases you should consider the benefits of DependencyProperties:

  • they are Bindable with WPF DataBinding (important e.g. for MVVM Pattern)
  • you see them in XAML Editor
  • you can inherit DependencyProperties as so called Attached Properties through controls without knowing each other
  • ...

The list is much longer. If you intend to use custom controls/user controls in WPF, you will see quite fast, that DependencyProperties are very usefull and essential for GUI development and not only a recommandation of Mircosoft.

Hope this was little helpfull

Jan

JanW
+1  A: 

The whole point of dependency properties, as their name (kind of obliquely) suggests, is that their value can depend on something else. Binding, value inheritance, and animation are three major ways that this is done:

  • Binding: The property's value depends on the data source it's bound to.
  • Value inheritance: The property's value depends on the value in its parent/ancestor object.
  • Animation: The property's value depends on the storyboard, which is changing its value over time.

What you posted doesn't "show the power of dependency properties." It shows what you have to go through to make it possible to take advantage of the power of dependency properties. You can't just create a CLR property with a backing field; you have to delegate the getter and setter to GetValue and SetValue, so that the CLR property and the dependency property system do the same thing.

Robert Rossney
Thanks for all the clarifications. This was helpful.
sc_ray