Monday, May 18, 2009

Element Binding in Silverlight 3.0 with a DatePicker Control

Binding control elements one with the other is a very powerful tool that can reduce writing code. Now with Silverlight 3 which is in beta this is easy. There are many examples wherein the values of a given element would depend on the setting of another control and binding elements would reduce the amount of code to be written otherwise. Although the code for the example chosen would have been very small, it could be substantial in other cases. This tutorial shows how to set the date on a date picker control that would display the date in a text box. Although the example by itself quite trivial, it brings out the essentials of element binding. In order to test this you need to have Visual Studio 2008 SP1 and Silverlight 3.0 installed on your machine.

Step 1: Create a Silverlight application

You create a Silverlight Application project from File | New |Project in Visual Studio 2008. Make sure you have displayed .NET Framework 3.5 in your New Project window as shown. Provide a name for your project. Herein it is called XmalianSL32.
When you click on OK Visual Studio creates an XmalianSL32 solution with an XmlaianSL32 VB project and an XmalianSL32.web project as shown with all necessary folders and files.

The web project has both an ASPX page as well as an HTML page. When you browse this (Right click XmalianSL32.aspx (or XmalianSL32.html) and choose
View in Browser) you would bring up the web (or html) page in a sand-boxed web site [you do not need a separate web server for this]. However the project may also be placed in a folder in the local web server's root directory. In the case of the HTML page you would see an embedded Silverlight object with the MimeType="applicaiton/x-silverlight-2". In the case of the ASPX page you will see a ASP:Silverlight control (review the source code for both). Well, this is two birds with one stone!!. The Object or the control both gets their XAML from the MainPage.XAML in the project.

Step 2: Place a Stack Panel in the grid 

When you double click the MainPage.xaml you would open the XMAL code with its preview XMAL as shown. The default layout scheme is grid. The white area you see in the preview is the grid.
Place a StackPanel inside the grid. Contrary what you would do in Visual Studio with other projects you may be tempted to drag and drop a StackPanel from the Toolbox and drop it in XMAL. You cannot drag and drop it into what appears like a design area. Because this is only a preview window for the XMAL code. You may however drag and drop the Stack Panel inside the XMAL code. When you do this you will see that the preview changes as shown. When you make changes to the code you may also hit on the Build menu item to load the XMAL code. I just colorized the stack panel to orient myself as shown. You may also add other attributes which are supported by intellisense as shown. As of now you cannot edit the properties in the property window as you might be doing for other project types.

Step3: Drag and drop DatePicker and a Textbox to the Stack Panel

Drag and drop a DatePicker control and a Textbox control from Toolbox |Silverlight XAML Controls shown.
These get added to the stack panel as shown. Provide a name to the DataPicker as shown[x:Name="dpx"]. In doing this you have intellisense support.

<StackPanel Width="200" Height="60" 
                    Background="LawnGreen" >
            <controls:DatePicker x:Name="dp" Visibility="Visible"></controls:DatePicker>
            <TextBox Text=""></TextBox>

You can see that the DatePicker and the Textbox are unrelated. So if you browse the page you would see the following displayed.

When you pick a date in the date picker it is not displayed in the textbox as they are unrelated.

Step 4: Bind the controls using the Element Name

In the next step you will bind the DatePicker to the Textbox using the Element Name which you provided for the DatePicker.
Now build the solution and browse to the page (either of the ASPX or HTML). When the page gets displayed click on the DatePicker to open up and click on a date. The date you picked gets displayed in the textbox.
Note that you could have accomplished the same using code by assigning the DatePicker's date property to the textbox's text property.
It may be noted that the project files were placed in a folder on the root directory of the Local IIS web server as shown. This folder can be accessed with anonymous authentication with read only privileges. You may browse the HTML page from here (IIS).

Reversing the role of TextBox and DatePicker

In the previous case the DatePicker drove what was displayed in the TextBox. It can be the other way as well. However in order to do this you need to bind the appropriate property for the DatePicker. How would one know what property of one element can be bound to what property of the other element? You may know this by looking at the properties that are accessible from a drop-down list that intellisense provides. This is shown in the next figure.

Now you can try binding the DisplayDate of the Calendar part of the DatePicker to the value that is in the text box. If you already have a hard-coded date in the textbox the calendar would display that date when you browse either of the ASPX or HTML pages.

After editing the XAML markup of the two controls, the XMAL code is as shown here. An extra Label control is also added with its Content property bound to the textbox. If the Textbox is hard-coded with its Text property it would be immediately visible for the Label but not for the DatePicker.

Browsing either of the pages (HTML or ASPX) and then typing in a date in the Textbox would set the date of the Calendar part of the DatePicker to the date entered as shown here. 

Binding with properties within the same element

It is also possible to bind one property of an element to another property in the same element. Changes were made to the XMAL mark up to test the binding.

<UserControl xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  xmlns:dataControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm"  x:Class="XmalianSL33.MainPage"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel Width="200" Height="80"
                    Background="LawnGreen" >
            <controls:Label Background="PowderBlue"
                 Content="{Binding Text,ElementName=tb}">        
            <TextBox x:Name="tb" Text="2/2/2020"></TextBox>
            <controls:DatePicker  x:Name="dp"
                 DisplayDate="{Binding Text,ElementName=tb}"
                 Text="{Binding DisplayDate, ElementName=dp}"

The above code would work when (the first time) you browse as seen in the following browser display.

However when you change the textbox entry to something different in the browser, the display in the Calendar synchronizes with the textbox change but the text of the DatePicker does not. One of the reasons for this could be that between an existing content and the one referenced by the ElementName, the existing content has precedence.


The article described the essentials of codeless Element Binding in Silverlight 3.0 using a very simple example. A variation of Element Binding was tested for binding of properties within the same element with limited success. Visual Studio 2008 allows you to choose any of the browsers on your machine. IE 8 used in the preparation of this article was too slow to respond and was changed over to Safari browser. The other option for viewing the pages is the internal browser in Visual Studio.

No comments: Protection Status