Geeks With Blogs
Peter Tweed Exploring and explaining the mysteries of .NET

When building applications we usually want to adopt the write once user everywhere or DRY (Don’t Repeat Yourself) goals for simpler maintenance, validation, configuration,etc etc. So for business applications the situation is usually develop a control, that can be re-used and that can have different data bound to it for the situation in which it is used.

 has a fantastic mechanism – the Silverlight Property System - that manages data binding among other things.  This means that the late binding infrastructure for data binding is supplied for us.  We just need to be able to tie in our user control properties to the Silverlight Property system so it can do the heavy lifting for binding our data.

So to demonstrate this we’ll do the following:

a)      Create a user control with a string property

b)      Use the user control on a page

c)      Data bind the string property

d)     See what we need to do to make it data bind successfully

This app is built on , , and the using .

The code for this post can be found here.

Steps:

1.      Create a Silverlight application (I called mine SLDataBinding) and add a user control (I called mine MyDataBoundControl).  Copy the following XAML into the grid of the user control to define the layout of the control.  (I also removed the width and height on the user control to have the user control dynamically size itself).

        <StackPanel Orientation="Horizontal" >

            <TextBlock Text="Bound Data:" />

            <TextBlock x:Name="txtBoundData" />

        </StackPanel>

2.      Copy the following C# property definition into the code behind of the user control

        private String _myTextValue;

 

        public String MyText

        {

            get { return _myTextValue; }

            set {

                _myTextValue = value;

                txtBoundData.Text = value;

            }

        }

 

Add the namespace reference for your Silverlight project to the top of the Page.xaml file

    xmlns:myProj="clr-namespace:SLDataBinding"

 

3.      Copy the following XAML to the grid of the Page.xaml file to declare an instance of our user control and set the custom property

        <myProj:MyDataBoundControl MyText="Hello World!" />

4.      Run the application

5.      Great – so far so good.  But this isn’t useful.  The scenario we need is to have a business object property bound to the MyText on our custom user control.  Add a class file to our Silverlight project and add a string property.  My class is below:

using System;

 

namespace SLDataBinding

{

    public class MyClass

    {

        private String _myValue;

 

        public String MyValue

        {

            get { return _myValue; }

            set { _myValue = value; }

        }

    }

}

6.      In Page.xaml add the following xaml above the Grid control to instantiate an object of our custom class and make it available within the scope of Page.xaml.

    <UserControl.Resources>

        <myProj:MyClass MyValue="Hello World from a custom class!" x:Name="MyObject" />

    </UserControl.Resources>

7.      In Page.xaml add the following attribute definition to the LayoutRoot Grid

DataContext="{StaticResource MyObject}"

8.      In Page.xaml change our control declaration to

        <myProj:MyDataBoundControl MyText="{Binding MyObject.MyValue}" />

9.      Great we have defined a class, declared an instance of it and bound the instance property to the property of our custom control.  Let’s see what happens when we run the app

10.  This is the really useful error that Silverlight throws when you try to bind a value to a property that is not a DEPENDENCY PROPERTY.  It doesn’t tell us that but it’s what it means in our situation.  Yes the exception description and reporting mechanism could do with a lot of work in Silverlight!

11.  So we need to change our standard C# property into a dependency property.  Why?  This is the way we register custom properties on controls with the Silverlight property system so the Silverlight property system can do that heavy lifting for late binding that we talked about earlier.

12.  Copy the following code to replace our C# property in our custom control

        public static readonly DependencyProperty MyTextProperty =

            DependencyProperty.Register("MyText",

            typeof(String), typeof(MyDataBoundControl),

            new PropertyMetadata(MyTextChanged));

This is the definition of our dependency property for our custom control.  It is what registers a property called MyText of type String for the class MyDataBoundControl with the Silverlight property system.  Also it defines an event handler called MyTextChanged that is called when the MyText property value is changed.

13.  Copy the following code below the dependency property definition code

 

        public String MyText

        {

            get { return (String)GetValue(MyTextProperty); }

            set { SetValue(MyTextProperty, value); }

        }

 

This code defines a standard CLR property to wrap the dependency property management functions, so that a developer could interact with the property via code and not need to know that it’s a dependency property.  I’ve included this for FYI, but it is not needed for our example

14.  Copy the following code below the dependency property definition code

 

        private static void MyTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            MyDataBoundControl myControl = d as MyDataBoundControl;

 

            if (myControl != null)

            {

                if (e.NewValue != null)

                {

                    String text = e.NewValue as String;

                    myControl.txtBoundData.Text = text;

                }

            }

            else

            {

                myControl.txtBoundData.Text = String.Empty;

            }

        }

This code implements the event handler that will be called when the MyText dependency property changes.  This enables the Silverlight property system to manage all the late binding functions that should occur before the UI handles the change in dependency property value.  That’s why this pattern of implementation was used.

Note – you get a reference to the object (a dependency object – the instance of our custom control) on which the MyText property changed.  You can then interact with the controls within our custom control to set the new property value passed in via the NewValue property on the DependencyPropertyChangedEventArgs argument.

15.  Finally copy the code below to replace our MyClass definition

using System;

using System.ComponentModel;

 

namespace SLDataBinding

{

    public class MyClass:INotifyPropertyChanged

    {

 

        private String _myValue;

 

        public String MyValue

        {

            get { return _myValue; }

            set {

                _myValue = value;

                if (PropertyChanged != null)

                {

                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("MyValue"));

                }

            }

        }

 

    #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    }

}

For the dependency property to know it changed, the properties to which it is bound must inform it they have changed and hence must implement the INotifyPropertyChanged interface that has been around in .NET for years.

16.  Run the app

Congratulations you have implemented your own custom control that can take advantage of the data binding infrastructure of the Silverlight property system!

What have we done?

We have created our own custom user control.

We have added our custom control to a page (including the appropriate namespace reference)

We have seen what happens when we try to bind to properties not defined as dependency properties.

We have seen how to define a dependency property and how to handle the property changed event for the property.

Conclusion

The Silverlight property system provides the late binding infrastructure to provide developers with a powerful data binding mechanism.  To tap into this, developers need to define the properties on their custom controls as Dependency Properties.

Posted on Sunday, July 5, 2009 12:10 PM Silverlight | Back to top


Comments on this post: Taking advantage of data binding in Silverlight

# re: Taking advantage of data binding in Silverlight
Requesting Gravatar...
Wonderful! After wallowing through a hundred confusing examples, yours got me up and running in no time. Thanks for the post.

BTW, what are you using for code presentation and syntax highlighting on your blog?

-VP
Left by Vince Plaza on Sep 10, 2009 11:16 PM

# re: Taking advantage of data binding in Silverlight
Requesting Gravatar...
You are very welcome! Thanks for the feedback. It's always good to hear whether it's actually helping people or not :-).
Re: code presentation and syntax highlighting I simply copy and paste from Visual Studio to MS Word and then paste to the rich text editor used in with the GeeksWithBlogs blogging engine.
Left by Peter on Sep 13, 2009 10:34 AM

# re: Taking advantage of data binding in Silverlight
Requesting Gravatar...
Data binding in Silverlight? Cool... Thanks for showing us how!
Left by Home Interior Design Ideas on May 12, 2010 6:07 AM

# re: Taking advantage of data binding in Silverlight
Requesting Gravatar...
Why doesn't it fire validation if the binding is set to NotifyOnValidationError=True & ValidatesOnNotifyDataErrors=True? Is this a bug?
Left by Boom on Jun 22, 2010 11:11 AM

# What about two-way binding?
Requesting Gravatar...
How would you modify this to work with an editable TextBox rather than a TextBlock, where changes in the text box have to be propagated to the user control's dependency property and to the view model?
Left by KP on Sep 01, 2010 1:30 PM

# re: Taking advantage of data binding in Silverlight
Requesting Gravatar...
Dood, just one comment, ont he Page Xaml file, you have to switch the binding to just MyValue MyText="{Binding MyValue}"
Left by Soki on Mar 09, 2011 11:55 AM

Your comment:
 (will show your gravatar)


Copyright © PeterTweed | Powered by: GeeksWithBlogs.net