SilverLight FAQ's - Part 3

Introduction

This article discusses 12 FAQ's which revolve around bindings, layouts, consuming WCF services and how to connect to database through silver light.

Article first starts with bindings and discusses about one way, two way and one time bindings. Article then moves on to discuss three different ways to layout and position silverlight controls. Finally we end up the article talking about how to consume WCF services in Silverlight and how can we do database operations.


Other Silverlight FAQ's

Silverlight FAQ Part 1:- 21 FAQ's  This tutorial has 21 basic FAQ's which will help you understand WPF , XAML , help your 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 4 different ways of transforming the objects.

Can you explain one way and two way bindings ?

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.

 1.JPG

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 silver light UI text box. To bind the property you need to specify 'Binding Path=Year' in the text property of the text box UI object. 'Year' is the property which we are binding with the text box 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 text box data context with the date object just created.

   public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
        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 ensure 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.

 2.JPG

To implement two way binding there are two extra steps with 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>

Second change is 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.

 Can you explain One time binding?

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> 

Can you demonstrate a Simple example of OneWay and TwoWay?

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.

 3.JPG

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.

What are the different ways provided to do layout in SilverLight?

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.

Can you explain how Canvas layout actually works?

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.

 4.JPG

How can we implement Grid Layout?

Grid layout helps you position your controls using rows and columns. It's very similar to table defined in HTML.

 5.JPG

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 textblocks are placed in the appropriate sections.

How can we implement Stack Layout?

As the name so the behavior. Stack allows you to arrange your UI elements vertically or horizontally.
 

 6.JPG

For instance below are 4 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.

What are the different steps involved in consuming WCF service in Silverlight ?

To consume WCF service is a 4 steps procedure.

Step1:- Create your WCF Service

The first step is to create your WCF service. When we create a WCF service by default it creates 'GetData' function which takes in a 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);
        }
    }

Step 2 :- Enable cross domain for your WCF service

For this example our WCF service and the silver light 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 silver light web application is hosted in one domain like http://www.xyz.com/ and your WCF service is hosted in different domain i.e. http://www.pqr.com/ .

The WCF service needs to enable cross domain facility so that other domains can consume the WCF service.

 7.jpg

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.

<?xml version="1.0" encoding="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

<?xml version="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>
 
Step 3 :- Add the WCF service reference and call the service

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 the name space. In second step1 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.

8.JPG


One of the important points to note is that the function 'GetData' is called asynchronously.

Step 4:- Add the WCF service reference and call the service

Finally compile the program and enjoy the output.

 9.JPG

You can get this source code at the end of this article.

Why can't we consume ADO.NET directly in SilverLight?

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 can not 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.

 10.JPG
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.

 11.jpg

 Below are 7 important steps which we need to follow to consume a database WCF service in silverlight.

How can we do database operation using SilverLight?

Step 1:- Create the Service and Data service contract

Below is a simple customer table which has 3 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);
}

 
Step 2:- Code the WCF service

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;
    }
}

Step 3:- Copy the CrossDomain.xml and ClientAccessPolicy.XML file

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.

<?xml version="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> 

<?xml version="1.0" encoding="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>

Step 4:- Change the WCF bindings to 'basicHttpBinding'

Silverlight consumes and generates proxy for only 'basicHttpBinding' , so we need to change the endpoint bindings accordingly.

<endpoint address="" binding="basicHttpBinding" contract="WCFDatabaseService.IServiceCustomer">

Step 5:- Add service reference

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.
 
Step 6 :- Define the grid for Customer  Name and Customer Code

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>

Step 7:- Bind the WCF service with the GRID

Now that our grid is created its 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 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.

 12.JPG

Source Code

You can download the source code from the top of this article. 


Similar Articles