Monday, December 12, 2011

Silverlight Event

In Silverlight MSDB always says that the event are bubbled
Taken from MSDN
http://msdn.microsoft.com/en-us/library/cc189018%28v=vs.95%29.aspx

WPF supports an analogous "tunnelling" routing strategy, whereby the root of a page / object tree has the first chance to handle a routed event, and the event then "tunnels" down the object tree toward its event source. Silverlight does not use "tunnelling" routed events. Events in Silverlight either follow the "bubbling" routing strategy (and are referred to as routed events) or do not route at all. There are also other API-level differences in routed event behaviour between Silverlight and WPF.

Which means that in silver light there is no tunnelling.....

But with the below sample I am trying to show a bug in Silverlight Datagrid
when we subscribe the events for the selected item event.

In the below example , I have created a Data Grid which subscribe the selected item event, and the data grid have 2 columns .One is defined as DataGridTemplateColumn and another is a DataGridTextColumn.In the DataGridTemplateColumn I have placed a checkbox and subscribe the click event ...

Turn on the debugger and see when we clicked on the check box .....Which event got fired.....






                  




                       









namespace SilverlightApplication1
{
   public partial class MainPage : UserControl
    {
      public MainPage()
        {
          InitializeComponent();
          this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

     void MainPage_Loaded(object sender, RoutedEventArgs e)
      {
       List lstTest = new List();
       lstTest.Add(new Test { CheckFlag = true, StringCaption = "1" });
       lstTest.Add(new Test { CheckFlag = true, StringCaption = "2" });
       lstTest.Add(new Test { CheckFlag = true, StringCaption = "3" });
       lstTest.Add(new Test { CheckFlag = true, StringCaption = "4" });
       lstTest.Add(new Test { CheckFlag = true, StringCaption = "5" });
       lstTest.Add(new Test { CheckFlag = true, StringCaption = "6" });
       dgTest.ItemsSource = lstTest;
      }

   private void dgTest_SelectionChanged(object sender,SelectionChangedEventArgs  e)
    {

     }

  private void CheckBox_Click(object sender, RoutedEventArgs e)
   {

    }
}
public class Test
 {
  public bool CheckFlag { get; set; }
   public string StringCaption { get; set; }
 }
}

Looking into this and try to understand this whether this is a bubbling or not ..

Monday, November 28, 2011

Page Life Cycle

When a page request is sent to the Web server, the page is run through a series of events during its creation and disposal. In this article, I will discuss in detail the ASP.NET page life cycle Events

(1) PreInit The entry point of the page life cycle is the pre-initialization phase called “PreInit”. This is the only event where programmatic access to master pages and themes is allowed. You can dynamically set the values of master pages and themes in this event. You can also dynamically create controls in this event.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{   
 protected void Page_PreInit(object sender, EventArgs e)  
  {      
         //  Use this event for the following: 
         //  Check the IsPostBack property to determine whether this is the first time the page 
         //  is being processed.        
         //  Create or re-create dynamic controls.      
         //  Set a master page dynamically.        
         //  Set the Theme property dynamically.          
  }


(2)Init This event fires after each control has been initialized, each control's UniqueID is set and any skin settings have been applied. You can use this event to change initialization values for controls. The “Init” event is fired first for the most bottom control in the hierarchy, and then fired up the hierarchy until it is fired for the page itself.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected void Page_Init(object sender, EventArgs e)
{ 
   // Raised after all controls have been initialized and any skin settings have been applied.
   // Use this event to read or initialize control properties.
}



(3)InitComplete Raised once all initializations of the page and its controls have been completed. Till now the viewstate values are not yet loaded, hence you can use this event to make changes to view state that you want to make sure are persisted after the next postback

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected void Page_InitComplete(object sender, EventArgs e)
{       
        // Raised by the  Page object. Use this event for processing tasks 
        // that require all initialization be complete.
}



(4)PreLoad Raised after the page loads view state for itself and all controls, and after it processes postback data that is included with the Request instance

(1)Loads ViewState : ViewState data are loaded to controls
Note : The page viewstate is managed by ASP.NET and is used to persist information
over a page roundtrip to the server. Viewstate information is saved as a string of
name/value pairs and contains information such as control text or value. The
viewstate is held in the value property of a hidden input control that is passed
from page request to page request.

(2)Loads Postback data : postback data are now handed to the page controls

Note : During this phase of the page creation, form data that was posted to the
server (termed postback data in ASP.NET) is processed against each control that
requires it. Hence, the page fires the LoadPostData event and parses through the page
to find each control and updates the control state with the correct postback data.
ASP.NET updates the correct control by matching the control's unique ID with the
name/value pair in the NameValueCollection. This is one reason that ASP.NET requires
unique IDs for each control on any given page.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected override void OnPreLoad(EventArgs e)
{      
         // Use this event if you need to perform processing on your page or control before
         // the  Load event.        
         // Before the Page instance raises this event, it loads view state for itself 
         // and all controls, and then processes any postback data included 
         // with the Request instance.
}



(5)Load The important thing to note about this event is the fact that by now, the page has been restored to its previous state in case of postbacks. Code inside the page load event typically checks for PostBack and then sets control properties appropriately. This method is typically used for most code, since this is the first place in the page lifecycle that all values are restored. Most code checks the value of IsPostBack to avoid unnecessarily resetting state. You may also wish to call Validate and check the value of IsValid in this method. You can also create dynamic controls in this method.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected void Page_Load(object sender, EventArgs e)
{       
      // The  Page calls the  OnLoad event method on the  Page, then recursively does the 
      // same for each child control, which does the same for each of its child controls until 
     //  the page and all controls are loaded.        
     //  Use the OnLoad event method to set properties in controls and establish 
     //  database connections.
}


(6)Control (PostBack) event(s)ASP.NET now calls any events on the page or its controls that caused the PostBack to occur. This might be a button’s click event or a dropdown's selectedindexchange event, for example.These are the events, the code for which is written in your code-behind class(.cs file).

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected void Button1_Click(object sender, EventArgs e)
{       
         // This is just an example of control event.. 
         // Here it is button click event that caused the postback
}


(7)LoadComplete This event signals the end of Load.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected void Page_LoadComplete(object sender, EventArgs e)
{       
        // Use this event for tasks that require that all other controls on the page be loaded.

}


(8)PreRender Allows final changes to the page or its control. This event takes place after all regular PostBack events have taken place. This event takes place before saving ViewState, so any changes made here are saved.For example : After this event, you cannot change any property of a button or change any viewstate value. Because, after this event, SaveStateComplete and Render events are called.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected override void OnPreRender(EventArgs e)
{        

        // Each data bound control whose DataSourceID property is set calls its DataBind method.
        // The PreRender event occurs for each control on the page. Use the event to make final 
        // changes to the contents of the page or its controls.

}


(9)SaveStateComplete Prior to this event the view state for the page and its controls is set. Any changes to the page’s controls at this point or beyond are ignored.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected override void OnSaveStateComplete(EventArgs e)
{       
             // Before this event occurs,  ViewState has been saved for the page and for all 
             // controls. Any changes to the page or controls at this point will be ignored.
             // Use this event perform tasks that require view state to be saved, but that do 
             // not make any changes to controls.
}

(10)Render This is a method of the page object and its controls (and not an event). At this point, ASP.NET calls this method on each of the page’s controls to get its output. The Render method generates the client-side HTML, Dynamic Hypertext Markup Language (DHTML), and script that are necessary to properly display a control at the browser.

Note: Right click on the web page displayed at client's browser and view the Page's Source. You will not find any aspx server control in the code. Because all aspx controls are converted to their respective HTML representation. Browser is capable of displaying HTML and client side scripts.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

 // Render stage goes here. This is not an event


(11)UnLoad This event is used for cleanup code. After the page's HTML is rendered, the objects are disposed of. During this event, you should destroy any objects or references you have created in building the page. At this point, all processing has occurred and it is safe to dispose of any remaining objects, including the Page object. Cleanup can be performed on-
(a)Instances of classes i.e. objects
(b)Closing opened files
(c)Closing database connections.

EXAMPLE : Override the event as given below in your code-behind cs file of your aspx page

protected void Page_UnLoad(object sender, EventArgs e)   
{       
          // This event occurs for each control and then for the page. In controls, use this 
          // event to do final cleanup for specific controls, such as closing control-specific
          // database connections.        
          // During the unload stage, the page and its controls have been rendered, so you 
          // cannot make further changes to the response stream.           
          //If you attempt to call a method such as the Response.Write method, the page will 
          // throw an exception.   
 }

Tuesday, November 22, 2011

Calling WCF From Silverlight Without Using Service Reference

Calling WCF From Silverlight Without Using Service Reference
In this article I will demonstrate how to call WCF service without using the Service Reference. Practical reasons of doing this as a developing is allowing us to have more control over our calls to WCF.

Basically I will introduce two ways of doing this;

1. Using the ChannelFactory

2. Using the ClientBase

To start calling WCF service to your Silverlight application first we have to copy the ServiceContract and DataContract codes to our silverlight projects.

namespace Demo.Wcf.Services
{
[System.ServiceModel.ServiceContract()]
public interface PersonService
{

[System.ServiceModel.OperationContract(AsyncPattern = true)]
IAsyncResult BeginGetPerson(int no, AsyncCallback callback, object state);

Person EndGetPerson(IAsyncResult result);

}

[System.Runtime.Serialization.DataContract()]
public class Person
{
private int _No;
[System.Runtime.Serialization.DataMember()]
public int No
{
get { return _No; }
set { }
}

private string _FirstName;
[System.Runtime.Serialization.DataMember()]
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value; }
}

private string _LastName;
[System.Runtime.Serialization.DataMember()]
public string LastName
{
get { return _LastName; }
set { _LastName = value; }
}

private DateTime _BirthDate;
[System.Runtime.Serialization.DataMember()]
public DateTime BirthDate
{
get { return _BirthDate; }
set { _BirthDate = value; }
}

public Person(int no)
{
_No = no;
}
}
}
First thing to note from the above code is the namespace should be the same namespace as the service definition. Secondly, the service methods will be defined using the Async pattern. Primary reason for doing this is Silverlght 2 only supports async operations to WCF calls. To define the service methods using async pattern is to define methods with Begin and End prefix (e.g. BeginGetPerson, EndGetPerson) and set the attribute OperationContract AsyncPattern parameter to true. This will instruct the runtime to interprete the methods prefixed by Begin and End.

Now we come to the most interesting part how to call the service. as mention we will implement this in wo ways

Using ChannelFactory

protected void Page_Loaded(object sender, RoutedEventArgs e)
{
PersonService svc = new ChannelFactory(
new BasicHttpBinding(),
new EndpointAddress("http://localhost:9902/PersonService.svc")).CreateChannel();
svc.BeginGetPerson(0,
delegate(IAsyncResult result)
{
Person p = ((PersonService)result.AsyncState).EndGetPerson(result);
this.Dispatcher.BeginInvoke(
delegate()
{
txtName.Text = p.FirstName;
}
);
},
svc);
}
As you can see from the above code that it is pretty straight forward similar on the how the ChannelFactory is being used by the .NET Framework. However important thing to note was to use the Dispatcher when assigning values to the control properties this is to avoid cross-thread errors.

Using the ClientBase

To use the ClientBase we need to create a class that will inherit the ClientBase class and for the sake of my implementation I suggest to create an event argument class as well. This is necessary because our implementatio will be using the event base pattern.


namespace Demo.Wcf.Services
{
public class PersonServiceEventArgs : EventArgs
{
private Person _Result;

public Person Result
{
get { return _Result; }
}

public PersonServiceEventArgs(Person result)
{
_Result = result;
}
}

public class PersonServiceClient : ClientBase
{
public event EventHandler GetPersonCompleted;

public PersonServiceClient(Binding binding, EndpointAddress endpoint) : base(binding, endpoint)
{

}

public void GetPersonAsync(int no)
{
IAsyncResult result = Channel.BeginGetPerson(no, GetPersonCallback, no);
}

private void GetPersonCallback(IAsyncResult result)
{
Person p = Channel.EndGetPerson(result);
if (GetPersonCompleted != null)
GetPersonCompleted(this, new PersonServiceEventArgs(p));
}

protected override PersonService CreateChannel()
{
return base.CreateChannel();
}
}
}
The above example is also straightforward is a sense that we implemented an event that will response when the call from WCF has been completed and the result will be retrieved from the event argument class that we created. Now to call this from your Silverlight is pretty simple also.

protected void Page_Loaded(object sender, RoutedEventArgs e)
{

PersonServiceClient proxy = new PersonServiceClient(new BasicHttpBinding(), new EndpointAddress("http://localhost:9902/PersonService.svc"));
proxy.GetPersonCompleted += delegate(object source, PersonServiceEventArgs args)
{
this.Dispatcher.BeginInvoke(
delegate()
{
txtName.Text = args.Result.FirstName;
}
);
};

proxy.GetPersonAsync(0);
}