DataBinding in Silverlight - Change property of a Silverlight UI Control at runtime based on another UI Control

Posted by: Suprotim Agarwal , on 11/16/2008, in Category Silverlight 2, 3, 4 and 5
Views: 41913
Abstract: In this example, we will see how to change the UI Property of a Silverlight Control based on the property of another control at runtime.
DataBinding in Silverlight - Change property of a Silverlight UI Control at runtime based on another UI Control
 
Before the title misleads you, there is no 'direct way' to do a databinding between the properties of two controls in Silverlight. A binding is a relationship between a UI property and a CLR object. The source can be any CLR object whereas the target must be a DependencyProperty of a FrameworkElement. In this example, we will change the UI Property of a Control based on the property of another control at runtime. We will take two elements: Rectangle and Slider and change the width of the Rectangle control using the Slider.
Note: In WPF, you can directly bind the property of a UI Element to another.
Now since there no way to do direct binding between two Silverlight controls, our requirement of changing the width of the Rectangle based on the Slider value looks a bit challenging. What we need is that whenever there is a change in the property value of the Source, we will have to implement a notification of some kind that propogates the change to the target. So how do we do it? Well enter the INotifyPropertyChanged Interface.
INotifyPropertyChanged Interface
To notify the Target of any changes in the Source, implement the INotifyPropertyChanged interface. This interface contains the PropertyChanged event, which occurs when a property value changes. This event accepts two parameters, the sender and changed property name. When raised, this property enables the Source to cause updates to propagate to the Target, by informing the binding engine that the source has changed. The Binding Engine in turn then updates the target value.
Let us create the Source Object. The Source object here would be a class that implements the INotifyPropertyChanged as shown below. The property is 'Wid':
C#
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
 
namespace SilverlightDataBinding
{
    public class MyWidth : INotifyPropertyChanged
    {
        int wid;
 
        public int Wid
        {
            get { return wid; }
            set { wid = value; OnPropertyChanged("Wid"); }
        }
       
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected virtual void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }       
    }
}
 
VB.NET
Imports System
Imports System.Net
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Ink
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports System.ComponentModel
 
Namespace SilverlightDataBinding
      Public Class MyWidth
            Implements INotifyPropertyChanged
            Private wid_Renamed As Integer
 
            Public Property Wid() As Integer
                  Get
                        Return wid_Renamed
                  End Get
                  Set(ByVal value As Integer)
                        wid_Renamed = value
                        OnPropertyChanged("Wid")
                  End Set
            End Property
 
            Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
 
            Protected Overridable Sub OnPropertyChanged(ByVal [property] As String)
                  RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs([property]))
            End Sub
      End Class
End Namespace
We have reached half way by creating a source that implements the INotifyChangedInterface. We now need to specify the Binding Mode for the Slider and Rectangle controls. The Mode indicates the direction of the data flow in the binding. Silverlight supports 3 Binding Modes:
1. OneTime - update the target only once with the Source value and never again.
2. OneWay  - (Default) Update the target with the source value and keep the target updated anytime the source data changes.
3. TwoWay - Update both the target and the source when either of the two changes.
 
Linking the bits
 
We'll see some action in a moment. I have changed the root Element in the Page.xaml from the Grid to Canvas.
 
Proceeding ahead, let us first refer to the source object in our Page.xaml. In the markup shown below, we have created a reference to the namespace of the source object (xmlns:w="clr-namespace:SilverlightDataBinding")
 
<UserControl x:Class="SilverlightDataBinding.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:w="clr-namespace:SilverlightDataBinding"
    >
The next step is to create an instance of the source object in the Resources section. I have set the initial value of Wid as 10.
    <Canvas.Resources>
        <w:MyWidth x:Name="MyWidth" Wid="10"/>
    </Canvas.Resources>
Finally we will add the some controls to demonstrate the three BindingModes as well as change the Width property of the Rectangle using the Slider. The entire Page.xaml will look similar to the following:
<UserControl x:Class="SilverlightDataBinding.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:w="clr-namespace:SilverlightDataBinding">
<Canvas x:Name="LayoutRoot" Background="White">
        <Canvas.Resources>
            <w:MyWidth x:Name="MyWidth" Wid="10"/>
        </Canvas.Resources>
<TextBlock Text="{Binding Wid, Source={StaticResource MyWidth}, Mode=OneTime}" Canvas.Left="40"/>
       
<Rectangle x:Name="Rect" Height="30" Canvas.Top="40" Canvas.Left="40" Fill="Blue" Width="{Binding Wid, Source={StaticResource MyWidth}, Mode=OneWay}"/>
 
<Slider x:Name="mySlider" Width="100" Minimum="0" Maximum="100" SmallChange="1" LargeChange="10" Canvas.Left="40" Canvas.Top="90" 
Value="{Binding Wid, Mode=TwoWay, Source={StaticResource MyWidth}}" />
 
</Canvas>   
</UserControl>
 
If you observe the TextBlock has a binding mode of OneTime, the Rectangle has a binding mode of OneWay and the Slider has a BindingMode of TwoWay. Keeping the BindingMode of the Slider as TwoWay enables the Slider to update the source when the value of the Slider changes.
Observe the Rectangle control
<Rectangle x:Name="Rect" Height="30" Canvas.Top="40" Canvas.Left="40" Fill="Blue" Width="{Binding Wid, Source={StaticResource MyWidth}, Mode=OneWay}"/>
Now since the Rectangle is using a OneWay mode and the Width property is set as a Target bound to the source, the source(MyWidth) notifies the Target(width property of the Rectangle) of any changes in the value of the source data. This is what causes the width of the Rectangle to change at runtime, whenever the Source value is updated.
So on running the application, observe that initially the values look similar to the ones shown in the screenshot below:
Data Binding Initial
When the user moves the slider, the Slider having a BindingMode of TwoWay updates the Source. The Source in turn updates the Target and the width of Rectangle increases. The value of the TextBlock remains as is since its BindingMode is set to OneTime.
Data Binding Final
As you saw in this article, we can create a source object that implements the INotifyPropertyChanged interface and notify Targets that bind to this source. Using this technique, you can give users control over the UI at runtime. Write back to me and let me know how you used this technique. The source code of this article can be downloaded from here. I hope this article was useful and I thank you for viewing it.
 If you liked the article,  Subscribe to my RSS Feed.
What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and a new one recently at The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for nine times in a row now. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that represents premium web sites and digital publications comprising of Professional web, windows, mobile and cloud developers, technical managers, and architects.

Get in touch with him on Twitter @suprotimagarwal, LinkedIn or befriend him on Facebook



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook