Wednesday 21 March 2012

Dynamically Generating Forms in WPF and Silverlight


Dynamically Generating Forms in WPF and Silverlight


Hi friends,

In this article you will know how to generate WPF form dynamically from property field.
Suppose we have requirement that create WPF form

First, we'll start with how to create form in XAML.

Creating forms at Design Time in XAML

 

Below form shows how to create form in XAML


<Grid Margin="10">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
              
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
  
    <TextBlock Text="First Name"    Height="19"
                Margin="0,7,31,4" />           
    <TextBox x:Name="FirstName"      Margin="3"
                Grid.Row="0"
                Grid.Column="1" />
              
    <TextBlock Text="Last Name"      Margin="0,7,6,3"
                Grid.Row="1"
                Height="20" />
    <TextBox x:Name="LastName"       Margin="3"
                Grid.Row="1"
                Grid.Column="1" />   
  
    <TextBlock Text="EmailId"      Grid.Row="2"
                Margin="0,9,0,0"
                Height="21" />
<TextBox x:Name=" EmailId "       Margin="3"
                Grid.Row="1"
                Grid.Column="1" />   
  
    <Button x:Name="Save"        Grid.Row="3"
            Grid.Column="3"   HorizontalAlignment="Right"
            VerticalAlignment="Top"     Margin="3"
            Width="80"        Height="25"
            Content="Save" />
</Grid>




Below diagram shows the how form shows




Creating forms at runtime using XAML strings

Below example shows the how to create form at runtime by using property class

1.  create a person class which has 10 properties


    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool isDefault { get; set; }
        public string EmailId { get; set; }
        public string EmployeeNo { get; set; }
        public string Age { get; set; }

        public string EmailId2 { get; set; }
        public bool isMale { get; set; }
        public string MobileNo { get; set; }
        public string TelephoneNo { get; set; }
    }



2. Creating Controls at runtime



We created following functions for creating textbox, textblock, row definition and for checkbox

functions CreateCheckBox() creates checkbox runtime

        private CheckBox CreateCheckBox(int row, int column)
        {
            CheckBox cb = new CheckBox();
            cb.Margin = new Thickness(5);
            cb.Height = 22;
            cb.MinWidth = 50;

            Grid.SetColumn(cb, column);
            Grid.SetRow(cb, row);

            return cb;
        }

        private RowDefinition CreateRowDefinition()
        {
            RowDefinition RowDefinition = new RowDefinition();
            RowDefinition.Height = GridLength.Auto;
            return RowDefinition;
        }




This will create a text block

private TextBlock CreateTextBlock(string text, int row, int column)
        {
            string[] aa = BreakUpperCB(text);
            string prop = "";
            for (int i = 0; i < aa.Length; i++)
            {
                 prop = prop +" "+ aa[i];
            }
TextBlock tb = new TextBlock() { Text = prop, Margin = new Thickness(5, 8, 0, 5) };
            tb.MinWidth = 90;
            tb.FontWeight = FontWeights.Bold;              
            tb.Margin = new Thickness(5);
            var bc = new BrushConverter();
            tb.Foreground = Brush)bc.ConvertFrom("#FF2D72BC");
            Grid.SetColumn(tb, column);
            Grid.SetRow(tb, row);          
            return tb;
        }
  






Handling Events


private TextBox CreateTextBox( int row, int column)
        {
            TextBox tb = new TextBox();
            tb.Margin = new Thickness(5);
            tb.Height = 22;
            tb.Width = 150;
            Grid.SetColumn(tb, column);
            Grid.SetRow(tb, row);
            return tb;
        }

// this will break the property text by upper
   public string[] BreakUpperCB(string sInput)
        {
            StringBuilder[] sReturn = new StringBuilder[1];
            sReturn[0] = new StringBuilder(sInput.Length);
            const string CUPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            int iArrayCount = 0;
            for (int iIndex = 0; iIndex < sInput.Length; iIndex++)
            {
                string sChar = sInput.Substring(iIndex, 1); // get a char
                if ((CUPPER.Contains(sChar)) && (iIndex > 0))
                {
                    iArrayCount++;
                    System.Text.StringBuilder[] sTemp = new System.Text.StringBuilder[iArrayCount + 1];
                    Array.Copy(sReturn, 0, sTemp, 0, iArrayCount);
                    sTemp[iArrayCount] = new StringBuilder(sInput.Length);
                    sReturn = sTemp;
                }
                sReturn[iArrayCount].Append(sChar);
            }
            string[] sReturnString = new string[iArrayCount + 1];
            for (int iIndex = 0; iIndex < sReturn.Length; iIndex++)
            {
                sReturnString[iIndex] = sReturn[iIndex].ToString();
            }
            return sReturnString;
        }

      void button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Saved Successfully");
        }

        private Button CreateButton(string text, int row, int column )
        {
            Button tb = new Button() { Content = text, VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(5, 8, 0, 5) };
            tb.Width = 90;
            tb.Height = 25;
            tb.Margin = new Thickness(5);
            Grid.SetColumn(tb, column);
            Grid.SetRow(tb, row);           
            return tb;
        }





In the below example we have created one function CreateControlsUsingObjects(Person obj) which create dynamic form based on the

Create Controls




        private void CreateControls(Person obj)
        {
            List<Person> objList=new List<Person>();

            objList.Add(obj);
            Grid rootGrid = new Grid();
            rootGrid.Margin = new Thickness(10.0);

            rootGrid.ColumnDefinitions.Add(
               new ColumnDefinition() { Width = new GridLength(100.0) });
            rootGrid.ColumnDefinitions.Add(
                 new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });

            rootGrid.ColumnDefinitions.Add(
                new ColumnDefinition() { Width = new GridLength(100.0) });
            rootGrid.ColumnDefinitions.Add(
                   new ColumnDefinition() { Width = new GridLength(100.0) });
  

                PropertyInfo[] propertyInfos;
                propertyInfos = typeof(Person).GetProperties();
                rootGrid.RowDefinitions.Add(CreateRowDefinition());
                int j = 1;
              
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    if (propertyInfo.PropertyType.Name == "String")
                    {

                        rootGrid.RowDefinitions.Add(CreateRowDefinition());

                        var Label = CreateTextBlock(propertyInfo.Name, j, 0);
                        rootGrid.Children.Add(Label);

                        var Textbox = CreateTextBox(j, 1);
                        rootGrid.Children.Add(Textbox);
                        j++;
                    }
                    if (propertyInfo.PropertyType.Name == "Boolean")
                    {
                        rootGrid.RowDefinitions.Add(CreateRowDefinition());

                        var Label = CreateTextBlock(propertyInfo.Name, j, 0);
                        rootGrid.Children.Add(Label);

                        var Textbox =  CreateCheckBox(j, 1);
                        rootGrid.Children.Add(Textbox);
                        j++;
                    }

                   
                   
                }
                rootGrid.RowDefinitions.Add(CreateRowDefinition());
                var Button = CreateButton("Save",j + 1, 1);
                Button.Click += new RoutedEventHandler(button_Click);

                rootGrid.Children.Add(Button);
                LayoutRoot.Children.Add(rootGrid           
        }
}





In the above example we have shown that how to create WPF form dynamically.
Below output screen shows the output as we want

Output Screen



Summary

So, we've seen that there are three different ways you can display controls in Silverlight and WPF.
  • Use the design surface / XAML Editor / Blend and create them prior to compiling
  • Load XAML at runtime
  • Use CLR Objects at runtime



Good luck and please, let me know your feedback!
In this way you can learn difference between proxy and channel factory

If you have any query mail me to Sujeet.bhujbal@gmail.com     

Regards
Sujeet Bhujbal


------------------------------------------------------------------------------------------------
 Blog:  www.sujitbhujbal.blogspot.com
Personal Website :- http://sujitbhujbal.wordpress.com/
Contact me on 9822663535
---------------------------------------------------------------------------------

Sunday 18 March 2012

Difference between proxy and channel factory


Hi friends, 


In this article I will show you what difference between WCF Channel factory and Proxy.
There are 3 basic ways to create a WCF client:
1.      Proxy
2.      WCF Channel Factory
3.      REST services, using the HttpClient or WebClient
Before the difference I will explain you what is WCF channel factory and what is proxy


1.   What is Proxy:
The proxy is a CLR class that exposes a single CLR interface representing the service contract. The proxy provides the same operations as service's contract, but also has additional methods for managing the proxy life cycle and the connection to the service. The proxy completely encapsulates every aspect of the service: its location, its implementation technology and runtime platform, and the communication transport.

The proxy can be generated using Visual Studio by right clicking Reference and clicking on Add Service Reference. This brings up the Add Service Reference dialog box, where you need to supply the base address of the service (or a base address and a MEX URI) and the namespace to contain the proxy. Let Visual Studio generate your proxy. This auto generates code that connects to the service by reading the WSDL. If the service changes for any reason you have to regenerate it. The big advantage of this is that it is easy to set up - VS has a wizard and it's all automatic. The disadvantage is that you're relying on VS to do all the hard work for you, and so you lose cont

Proxy can also be generated by using SvcUtil.exe command-line utility. We need to provide SvcUtil with the HTTP-GET address or the metadata exchange endpoint address and, optionally, with
When we generate (WCF) service proxy class for a service by using svcutil.exe, it creates a proxy that derives from System.ServiceModel.ClientBase<TChannel>. The proxy implements IDisposable and the client code can be wraped inside using statement and guaranteed clean-up in the face of exceptions.



2.   What is Channel Factory :

Use ChannelFactory with a known interface. This relies on you having local interfaces that describe the service (the service contract). The big advantage is that can manage change much more easily - you still have to recompile and fix changes, but now you're not regenerating code, you're referencing the new interfaces. Commonly this is used when you control both server and client as both can be much more easily mocked for unit testing
In order to use ChannelFactory<T> you must be willing to share contract assemblies between the service and the client. If this is okay with you then ChannelFactory<T> can save you some time.
When you share a common service contract dll between the client and the server, you'll be using the ChannelFactory class
When we use channel factory following steps to do
  1. Create a binding
  2. Create a ChannelFactory.
  3. Create a Channel
  4. Send/Receive messages over that channel.


In this example this is done by using ChannelFactory. Once the channel is in place we can send messages back and forth to the service.
using System;
using System.ServiceModel;
using EchoClientConsole.EchoServiceReference;

namespace EchoClientConsole
{
    internal class Program
    {
        private static void Main()
        {
            var channelFactory =
                new ChannelFactory<IEchoService>(
                    "WSHttpBinding_IEchoService" // config endpoint name
                    );

            IEchoService channel = channelFactory.CreateChannel();
            EchoMessage result = channel.Echo(
                new EchoMessage
                    {
                        Text = "Hey "
                    });

            Console.WriteLine("Service responded at {0}: {1}",
                              result.Invoked,
                              result.Text);
            Console.ReadLine();

            ((IClientChannel)channel).Close();
        }
    }
}


3.   Difference between proxy and channel factory


PROXY
Channel Factory
1
Only require URL where the service resides

You must have direct access to the assembly that contains that service contract T for
2
Very Simpler

Not easier
3
Easy to Understand
channels are complex, network-related
4
There is Visual Studio gives you add the reference
When you share a common service contract dll between the client and the server, you'll be using the ChannelFactory class
5
Proxies have several restrictions like:
  1. Properties need to have gets and sets
  2. Contructors can't be exposed
  3. Methods other than the service contract cannot be exposed

If you know that your entities will not change much and the client code is less, then a DLL would work better than a proxy
6
By using SVCutil.exe you will create PRoxy
When you are using DLL that refers Service contract interface then use the channel factory class




Good luck and please, let me know your feedback!
In this way you can learn difference between proxy and channel factory

If you have any query mail me to Sujeet.bhujbal@gmail.com     

Regards
Sujeet Bhujbal


------------------------------------------------------------------------------------------------
 Blog:  www.sujitbhujbal.blogspot.com
Personal Website :- http://sujitbhujbal.wordpress.com/
Contact me on 9822663535
---------------------------------------------------------------------------------