This article discusses 12 FAQs which revolve around bindings, layouts, consuming WCF services and how to connect to database through Silverlight.
Update: Links to other articles have been moved to the bottom of this article.
Table of Contents
Video demonstration One Way, Two Way and One Time Bindings using Silverlight
This article discusses 12 FAQs which revolve around bindings, layouts, consuming WCF services and how to connect to database through Silverlight. It starts with bindings and discusses about one way, two way and one time bindings. The article then moves on to discuss three different ways to layout and position Silverlight controls. Finally, we end the article by talking about how to consume WCF services in Silverlight and how we can do database operations.
I have collected around 400 FAQ questions and answers in WCF, WPF, WWF, SharePoint, design patterns, UML, etc. Feel free to download these FAQ PDFs from here.
One Way Binding
As the name, so the behavior. In one way bindings, data flows only from object to UI and not vice-versa. For instance, you can have a textbox
called as ‘TxtYear
’ which is binded with an object having property ‘Year
’. So when the object value changes, it will be reflected on the Silverlight UI, but the UI cannot update the year
property in the object.
It’s a three step procedure to implement one way binding. First, create your class which you want to bind with the Silverlight UI. For instance, below is a simple class called as ‘ClsDate
’ with a ‘Year
’ property.
public class clsDate
{
private int _intYear;
public int Year
{
set
{
_intYear = value;
}
get
{
return _intYear;
}
}
}
In the second step, you need to tie up the ‘Year
’ property with a Silverlight UI text box. To bind the property, you need to specify ‘Binding Path=Year
’ in the text
property of the textbox
UI object. ‘Year
’ is the property which we are binding with the textbox
UI object.
<TextBox x:Name="txtCurrentYear" Text="{Binding Path=Year}"
Height="30" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center">
</TextBox>
The final step is to bind the textbox
data context with the date object just created.
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
clsDate objDate = new clsDate();
objDate.Year = DateTime.Now.Year;
txtCurrentYear.DataContext = objDate;
}
}
Two Way Binding
Two way binding ensures data synchronization of data between UI and Objects. So any change in object is reflected to the UI and any change in UI is reflected in the object.
To implement two way binding, there are two extra steps in addition to the steps provided for ‘OneWay
’. The first change is we need to specify the mode as ‘TwoWay
’ as shown in the below XAML code snippet.
<TextBox x:Name="txtEnterAge" Text="{Binding Path=Age, Mode=TwoWay}"
Height="30" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center">
</TextBox>
The second change is that we need to implement ‘INotifyPropertyChanged
’ interface. Below is the class which shows how to implement the ‘INotifyPropertyChanged
’ interface. Please note you need to import ‘System.ComponentModel
’ namespace.
public class clsDate : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _intYear;
public int Year
{
set
{
_intYear = value;
OnPropertyChanged("Year");
}
get
{
return _intYear;
}
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(property));
}
}}
The binding of data with data context is a compulsory step which needs to be performed.
In one time binding, data flows from object to the UI only once. There is no tracking mechanism to update data on either side. One time binding has marked performance improvement as compared to the previous two bindings discussed. This binding is a good choice for reports where the data is loaded only once and viewed.
<TextBox x:Name="txtEnterAge" Text="{Binding Path=Age, Mode=OneTime}"
Height="30" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center">
</TextBox>
Below is a simple sample code where in we have two text boxes one takes in the age and the other text box calculates the approximate birth date.
Below is a simple class which has both the properties. We have implemented ‘INotifyPropertyChanged
’ interface so that we can have two way communication for the year
property.
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 SilverLightBinding
{
public class clsDate : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _intYear;
private int _intAge;
public int Year
{
set
{
_intYear = value;
OnPropertyChanged("Year");
}
get
{
return _intYear;
}
}
public int Age
{
set
{
_intAge = value;
Year = DateTime.Now.Year - _intAge;
}
get
{
return _intAge;
}
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(property));
}
}
}
}
Finally, we have also binded the SilverLight UI objects with the class properties. Below is the XAML snippet for the same. One point to be noted is that ‘Age
’ is bounded using two way mode as we need to modify the same from the user interface.
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"> Enter your age in the below text box</TextBlock>
<TextBox x:Name="txtEnterAge" Text="{Binding Path=Age, Mode=TwoWay}"
Height="30" Width="150" VerticalAlignment="Center"
HorizontalAlignment="Center"></TextBox>
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center">Your approximate birth date</TextBlock>
<TextBox x:Name="txtCurrentYear" Text="{Binding Path=Year}" Height="30"
Width="150" VerticalAlignment="Center"
HorizontalAlignment="Center"></TextBox>
You can download the source code for the same at the end of this article.
There are three ways provided by Silverlight for layout management Canvas
, Grid
and Stack
panel. Each of these methodologies fit in to different situations as per layout needs. All these layout controls inherit from Panel
class. In the further sections, we will go through each of them to understand how they work.
Canvas
is the simplest methodology for layout management. It supports absolute positioning using ‘X
’ and ‘Y
’ coordinates. ‘Canvas.Left
’ helps to specify the X co-ordinate while ‘Canvas.Top
’ helps to provide the ‘Y
’ coordinates.
Below is a simple code snippet which shows how a rectangle object is positioned using ‘Canvas
’ on co-ordinates (50
,150
).
<Canvas x:Name="MyCanvas">
<Rectangle Fill="Blue" Width="100"
Height="100"
Canvas.Left="50"
Canvas.Top="150"/>
</Canvas>
Below is how the display looks like. When you the run the code, the XAML viewer will position the rectangle object on absolute ‘X
” and ‘Y
’ coordinates.
Grid layout helps you position your controls using rows and columns. It’s very similar to table defined in HTML.
Below is a simple table with two columns and two rows defined using ‘Grid
’. We have shown how the table display looks like. Using the ‘Grid.ColumnDefinition
’, we have defined two columns and using ‘Grid.RowDefinition
’, we have defined two rows. We have then created 4 text blocks which are then specified in each section using ‘Grid.Column
’ and ‘Grid.Row
’. For instance, to place in the first column we need specify the ‘Grid.Column
’ as ‘0
’ and ‘Grid.Row
’ as ‘0
’. We have followed the same pattern for everyone and you can see all the textblock
s are placed in the appropriate sections.
As the name, so the behavior. Stack allows you to arrange your UI elements vertically or horizontally.
For instance, below are four elements which are arranged in a stack panel element. You can see how the stack aligns / stacks the elements one above other. You can also stack the UI elements horizontally or vertically depending on your layout nature.
You can get a simple source code which demonstrates the three layouts at the end of this article.
To consume WCF service is a four step procedure.
The first step is to create your WCF service. When we create a WCF service by default, it creates ‘GetData
’ function which takes in an integer value and returns back a string
saying “You entered 10
” , in case you have passed ‘10
’ as value to the function. We will try to consume this service in Silverlight in the coming steps.
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
For this example, our WCF service and the Silverlight web application will be hosted in different IIS website. In other words, they will be hosted in different domains. When we talk about different website in other words, they are hosted in different domains. For instance, it’s possible that your Silverlight web application is hosted in one domain like www.xyz.com and your WCF service is hosted in different domain, i.e., www.pqr.com.
The WCF service needs to enable cross domain facility so that other domains can consume the WCF service.
Figure: Cross domain
We need to create two XML files (clientaccesspolicy.xml and crossdomain.xml) in the root directory of the WCF service to enable cross domain functionality.
Below is the XML code snippet for clientaccesspolicy.xml.
="1.0"="utf-8"
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Below is the XML code snippet for crossdomain.xml.
="1.0"
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
Create a simple Silverlight application and add the service reference to your Silverlight project. In order to call the WCF service, we need to define event handlers.To consume the WCF service is a three step procedure. In the first step, refer to the name space. In the second step, create the object of your WCF service. In the final step, we need to create a event handler which will get the results sent by the WCF service.
One of the important points to note is that the function ‘GetData
’ is called asynchronously.
Finally, compile the program and enjoy the output.
You can get this source code at the end of this article.
Below are the different ingredients which constitute Silverlight plugin. One of the important points to be noted is that it does not consist of ADO.NET. In other words, you cannot directly call ADO.NET code from Silverlight application. Now the other point to be noted is that it has the WCF component. In other words, you can call a WCF service.
In other words, you can create a WCF service which does database operations and Silverlight application will make calls to the same. One more important point to be noted is do not return ADO.NET objects like dataset, etc. because Silverlight will not be able to understand the same.
Below are seven important steps which we need to follow to consume a database WCF service in Silverlight.
Below is a simple customer table which has three fields ‘CustomerId
’ which is an identity column, ‘CustomerCode
’ which holds the customer code and ‘CustomerName
’ which has the name of the customer. We will fire a simple select
query using WCF and then display the data on the Silverlight grid.
Field | Datatype |
CustomerId | int |
CustomerCode | nvarchar(50) |
CustomerName | nvarchar(50) |
As per the customer
table specified above, we need to first define the WCF data contract. Below is the customer
WCF data contract.
[DataContract]
public class clsCustomer
{
private string _strCustomer;
private string _strCustomerCode;
[DataMember]
public string Customer
{
get { return _strCustomer; }
set { _strCustomer = value; }
}
[DataMember]
public string CustomerCode
{
get { return _strCustomerCode; }
set { _strCustomerCode = value; }
}
}
We also need to define a WCF service contract which will be implemented by WCF concrete classes.
[ServiceContract]
public interface IServiceCustomer
{
[OperationContract]
clsCustomer getCustomer(int intCustomer);
}
Now that we have defined the data contract and service contract, it’s time to implement the service contract. We have implemented the ‘getCustomer
’ function which will return the ‘clsCustomer
’ datacontract
. ‘getCustomer
’ function makes a simple ADO.NET connection and retrieves the customer
information using the ‘Select
’ SQL query.
public class ServiceCustomer : IServiceCustomer
{
public clsCustomer getCustomer(int intCustomer)
{
SqlConnection objConnection = new SqlConnection();
DataSet ObjDataset = new DataSet();
SqlDataAdapter objAdapater = new SqlDataAdapter();
SqlCommand objCommand = new SqlCommand
("Select * from Customer where CustomerId=" + intCustomer.ToString());
objConnection.ConnectionString =
System.Configuration.ConfigurationManager.ConnectionStrings["ConnStr"].ToString();
objConnection.Open();
objCommand.Connection = objConnection;
objAdapater.SelectCommand = objCommand;
objAdapater.Fill(ObjDataset);
clsCustomer objCustomer = new clsCustomer();
objCustomer.CustomerCode = ObjDataset.Tables[0].Rows[0][0].ToString();
objCustomer.Customer = ObjDataset.Tables[0].Rows[0][1].ToString();
objConnection.Close();
return objCustomer;
}
}
This WCF service is going to be called from an outside domain, so we need to enable the cross domain policy in the WCF service by creating ‘CrossDomain.xml’ and ‘ClientAccessPolicy.xml’. Below are both the code snippets. The first code snippet is for cross domain and the second for client access policy.
="1.0"
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
="1.0"="utf-8"
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Silverlight consumes and generates proxy for only ‘basicHttpBinding
’ , so we need to change the endpoint bindings accordingly.
<endpoint address="" binding="basicHttpBinding" contract="WCFDatabaseService.IServiceCustomer">
We need to consume the service reference in silverlight application using ‘Add service reference’ menu. So right click the Silverlight project and select add service reference.
Now on the Silverlight side, we will create a ‘Grid
’ which has two columns, one for ‘CustomerCode
’ and the other for ‘CustomerName
’. We have also specified the bindings using ‘Binding path’ in the text block.
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock x:Name="LblCustomerCode" Grid.Column="0"
Grid.Row="0" Text="Customer Code"></TextBlock>
<TextBlock x:Name="TxtCustomerCode" Grid.Column="1"
Grid.Row="0" Text="{Binding Path=CustomerCode}"></TextBlock>
<TextBlock x:Name="LblCustomerName" Grid.Column="0"
Grid.Row="1" Text="Customer Name"></TextBlock>
<TextBlock x:Name="TxtCustomerName" Grid.Column="1"
Grid.Row="1" Text="{Binding Path=Customer}"></TextBlock>
</Grid>
Now that our grid is created, it's time to bind the WCF service with the grid. So go to the behind code of the XAML file and create the WCF service object. There are two important points to be noted when we call WCF service using from Silverlight:
- We need to call the WCF asynchronously, so we have called ‘
getCustomerAsynch
’. Please note this function is created by WCF service to make asynchronous calls to the method / function. - Once the function completes its work on the WCF service, it sends back the message to Silverlight client. So we need to have some kind of delegate method which can facilitate this communication. You can see that we have created a ‘
getCustomerCompleted
’ method which captures the arguments and ties the results with the grid ‘datacontext
’.
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
ServiceCustomerClient obj = new ServiceCustomerClient();
obj.getCustomerCompleted +=
new EventHandler<getCustomerCompletedEventArgs>(DisplayResults);
obj.getCustomerAsync(1);
}
void DisplayResults(object sender, getCustomerCompletedEventArgs e)
{
LayoutRoot.DataContext = e.Result;
}
}
You can now run the project and see how the Silverlight client consumes and displays the data.
Silverlight FAQ Part 1
This tutorial has 21 basic FAQs which will help you understand WPF, XAML, help you build your first Silverlight application and also explains the overall Silverlight architecture.
SilverLight FAQ Part 2 (Animations and Transformations)
This tutorial has 10 FAQ questions which starts with Silverlight animation fundamentals and then shows a simple animated rectangle. The article then moves ahead and talks about four different ways of transforming the objects.
- 23rd June, 2009: Initial version
For further reading do watch the below interview preparation videos and step by step video series.