Monday, July 20, 2009

Silverlight 3.0, RIA services and MVVM

MVVM == Model View ViewModel Pattern is a MUST follow pattern in Silverlight (WPF). here is why…

Problems it solves:

•Tight coupling of layers (ex a query in the UI)

•Unit testing is hard/impossible, only functional testing is possible

•Assures codes still works correct after a change

•ViewModel

•Provides View with data model and behavior

•View will bind to ViewModel

•Wraps data access entirely

In light of new technologies like RIA services (which provides CRUD) operations out of the box it is imperative that users are tempted to overlook MVVM for sake of simplicity!!! However, the goodies MVVM brings along holds good in RIA services well… So what the roadmap to have MVVM , silverlight and RIA services???? I havnt found much on google (& BING!!!) but here is my humble take on that.

I plan to write more in my forthcoming blog but here is one example using nInject.

nInject is lightweight DI framework and is helpful in injecting VIEWMODEL right into XAML code!!! here is how…

   1: Title="Home"



   2:   DataContext="{Binding Path=HomeViewModel, Source={StaticResource serviceLocator}}"



   3:   Style="{StaticResource PageStyle}">




Notice … the datacontext (VIEW MODEL) is injected using ServiceLocator!! the service locater is itself a resource defined in APP.xaml





   1: Application   



   2:   x:Class="SilverlightApp.App"



   3:   xmlns:local="clr-namespace:SilverlightApp.ViewModel"



   4:   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"



   5:   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">



   6:  



   7:   <Application.Resources>



   8:   



   9:     <ResourceDictionary>



  10:       <ResourceDictionary.MergedDictionaries>



  11:         <ResourceDictionary Source="Assets/Styles.xaml"/>



  12:       </ResourceDictionary.MergedDictionaries>



  13:     </ResourceDictionary>



  14:         <local:ServiceLocator x:Key="serviceLocator" />



  15:     </Application.Resources>



  16:  



  17: </Application>




and Ninject code for Service Locater goes like…





   1: namespace SilverlightApp.ViewModel



   2: {



   3:     using Ninject.Core;



   4:     public class ServiceLocator



   5:     {



   6:         private static readonly IKernel kernel;



   7:  



   8:         static ServiceLocator()



   9:         {



  10:             if (kernel == null)



  11:             {



  12:                 kernel = new StandardKernel(new Module());



  13:             }



  14:         }



  15:  



  16:         public HomeViewModel HomeViewModel



  17:         {



  18:             get



  19:             {



  20:                 return kernel.Get<HomeViewModel>(); 



  21:             }



  22:         }



  23:  



  24:         public static T Get<T>()



  25:         {



  26:             return kernel.Get<T>();



  27:         }



  28:     }



  29: }




 



The commands are taken care by the SLExtensions. here is how…



I will be using and blogging about the following DI … Please feel free to write more… if you have anything to add..



1. Nikhil Silverlight FX… This is really good stuff; the only thing which is “does NOT” goes down well (to most of developers) is use of customized controls. Having said that i must say, personally, i love this approach and how Nikhil keep updating it with newest stuff!!!



2. CAB(Prism): I personally think it is more opt for WPF. Having said that it also follows “injection through interface” paradigm.. which sometimes introduces too much hassles…



3. MEF. Latest from Microsoft. Very promising, however yet to mature as a tool.



4. Caliburn: Excellent tool. I found it at codeplex…



 



My plan is to retest each of the above wrt SL3.0, RIA services abd MVVM in context abd post results on this blog.. and get more tractions on the results i get to..



Keep jotting your comments…



Technorati Tags: ,,

Silverlight 3.0 – TechEd on Roads

I presented “What's new in silverlight 3.0” at Teched, Delhi on roads and got overwhelming response for it. Actually there was two events. The venue for the first event was Microsoft office, Gurgaon, Delhi. I must admit i had to change gears because most of the attendees were new to “Silverlight” itself; and i was introducing them to Silverlight 3.0 version!!

So i was back to questions like

  • Why Silverlight?
  • What silverlight means to
    • Developer
    • Architect
    • Manager
    • End user

It did generated lots of interest and my deal on capturing user attention by hatching on to the psychology made it home to most of the users. Examples i gave was as simple as making a grid rotate (flip) to use the same screen space to display more data. OR blurring the grid so that user can concentrate on more relevant information on screen…

Both of the above were, interestingly speaking examples of new features of SL 3.0…

There was also this interesting bit about “what it takes to move to SL platform” and concerns like “I felt lots of resistance from developers in my team while moving away from ASP .net”

It took them a moment before that they realized that SL is actually easy to work on and most importantly its the same C#, VB.net model  developers leverage on. The results they get

  • looks awesome (UI is simply great)
  • Works on every browser and just the same(no more coding for each browser and its version)
  • coding actually is easy

Getting the resistance out is just a matter of fact to demonstrate “how convenient it is” to code in silverlight and the goodies (best practices) are just there out-of-the-box.

Attached the the presentation deck along with the demo.

the best part for me is the compliment from Bijoy (who himself is renowned Microsoft evangelist) on my comment ‘Good products need good evangelists’

Technorati Tags:

Wednesday, May 27, 2009

Microsoft Azure, Bull Dog, Zurich ???

Someone mentioned “Zurich” and I was again wondering how it was different from “Geneva” or “Zermatt”.

Finally searching got me into this very useful “codename” info.

And I thought only “open-source” can think of funny names.

Hope you will find it useful.

Hats off to Mary Jo Foley for compiling this… here is the list.

Technorati Tags: ,,

Monday, May 18, 2009

Empty Data template in Silverlight DataGrid

One of my colleagues mentioned the “missing feature” of silverlight datagrid where in a message needs to be displayed when no records are present in the datagrid Itemsource.

So the objective is to make a datagrid which have a Empty Data grid template which may be overridden in case there are no records in the datagrid Item source. Like below.

image

The datagrid itself is trivial. I have introduced 3 dependency properties and overridden the Datagrid and the DataTemplate itself.

Here is how the XAML looks like

 

   1: <local:DataGridWithEmptyTemplate ItemsSource="{Binding Person}"  x:Name="MyDataGrid" AutoGenerateColumns="True">



   2:            <local:DataGridWithEmptyTemplate.EmptyTemplate>



   3:                <local:EmptyDataTemplate Width="420.0" EmptyHeaderText="FirstName    |   LastName    |   Gender    " >



   4:                    <Border CornerRadius="5" BorderThickness="2" BorderBrush="Gray" Margin="5" >



   5:                        <Border.Background>



   6:                            <LinearGradientBrush EndPoint="0.512,1.154" StartPoint="0.512,0.154">



   7:                                <GradientStop Color="Red" Offset="1"/>



   8:                                <GradientStop Color="AntiqueWhite" Offset="0.339"/>



   9:                            </LinearGradientBrush>



  10:                        </Border.Background>



  11:                        <StackPanel Width="Auto" Background="Transparent">



  12:                            <TextBlock Text="No Records"  ></TextBlock>



  13:                            <TextBlock Text="Please change the criteria. This template may be changed using XAML!!"></TextBlock>



  14:                        </StackPanel>



  15:                    </Border>



  16:                </local:EmptyDataTemplate>



  17:            </local:DataGridWithEmptyTemplate.EmptyTemplate>



  18:        </local:DataGridWithEmptyTemplate>




you may notice the Width and EmptyHeaderText Properties of EmptyDataTemplate.



The code behind looks like





   1: public class EmptyDataTemplate : DataTemplate



   2:    {



   3:        public EmptyDataTemplate()



   4:        {



   5:            



   6:        }



   7:  



   8:        public string EmptyHeaderText



   9:        {



  10:            get



  11:            {



  12:                return (string)GetValue(EmptyHeaderTextProperty);



  13:            }



  14:            set



  15:            {



  16:                SetValue(EmptyHeaderTextProperty, value);



  17:            }



  18:        }



  19:  



  20:        public static readonly DependencyProperty EmptyHeaderTextProperty = DependencyProperty.Register(



  21:            "EmptyHeaderText", typeof(string), typeof(EmptyDataTemplate), new PropertyMetadata(null));



  22:  



  23:        public double Width



  24:        {



  25:            get



  26:            {



  27:                return (double)GetValue(WidthProperty);



  28:            }



  29:            set



  30:            {



  31:                SetValue(WidthProperty, value);



  32:            }



  33:        }



  34:  



  35:        public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(



  36:            "Width", typeof(double), typeof(EmptyDataTemplate), new PropertyMetadata(100.0,null));



  37:    }



  38:  



  39:    public class DataGridWithEmptyTemplate : DataGrid



  40:    {



  41:  



  42:        public static TextBlock textBlock = new TextBlock();



  43:  



  44:        public DataGridWithEmptyTemplate()



  45:        {



  46:  



  47:            this.Loaded += new RoutedEventHandler((o, e) =>



  48:            {



  49:                int count = 0;



  50:                base.ItemsSource = this.ItemsSource;



  51:                var q = (IEnumerable)base.ItemsSource;



  52:                if (q != null)



  53:                {



  54:                    foreach (var items in q)



  55:                    {



  56:                        count++;



  57:                    }



  58:                }



  59:                if (count == 0)



  60:                {



  61:                    EmptyDataTemplate nodeTemplate = (EmptyDataTemplate)this.EmptyTemplate;



  62:                    if (nodeTemplate != null)



  63:                    {



  64:                        DataGridTemplateColumn dataGridTemplateColumn = new DataGridTemplateColumn();



  65:                        



  66:                        dataGridTemplateColumn.CellTemplate = nodeTemplate;



  67:                        dataGridTemplateColumn.Header = nodeTemplate.EmptyHeaderText;



  68:                        dataGridTemplateColumn.Width = new DataGridLength(nodeTemplate.Width);



  69:                        // we can even display the properties of object binded. 



  70:                        //var properties = from propertyInfo in typeof(Person).GetProperties()



  71:                        //                 select propertyInfo.Name;



  72:                        //foreach (string header in properties)



  73:                        //{



  74:                        //    d.Header = d.Header + header + "  |  ";



  75:                        //}



  76:                        FrameworkElement frameworkElement = dataGridTemplateColumn.CellTemplate.LoadContent() as FrameworkElement;



  77:                        this.Columns.Add(dataGridTemplateColumn);



  78:                        base.ItemsSource = new List<UIElement>() { frameworkElement };



  79:                        base.AutoGenerateColumns = false;



  80:                    }



  81:                }



  82:            }



  83:            );



  84:        }



  85:  



  86:        public EmptyDataTemplate EmptyTemplate



  87:        {



  88:            get



  89:            {



  90:                return (EmptyDataTemplate)GetValue(EmptyTemplateProperty);



  91:            }



  92:            set



  93:            {



  94:                SetValue(EmptyTemplateProperty, value);



  95:            }



  96:        }



  97:  



  98:        public static readonly DependencyProperty EmptyTemplateProperty = DependencyProperty.Register(



  99:            "EmptyTemplate", typeof(EmptyDataTemplate), typeof(DataGridWithEmptyTemplate), new PropertyMetadata(null));



 100:  



 101:    }




So, even if you forget to assign Itemsource or assigned itemsource which have zero items like before



MyDataGrid.ItemsSource = null;/// or even if you forget to assign Itemsource



MyDataGrid.ItemsSource = new List<Person>();



The result is same as below. You may override the template too!!!





   1: <local:DataGridWithEmptyTemplate ItemsSource="{Binding Person}"  x:Name="MyDataGrid" AutoGenerateColumns="True">



   2:             <local:DataGridWithEmptyTemplate.EmptyTemplate>



   3:                 <local:EmptyDataTemplate Width="420.0" EmptyHeaderText="FirstName    |   LastName    |   Gender    " >



   4:                     <Border CornerRadius="5" BorderThickness="2" BorderBrush="Gray" Margin="5" >



   5:                         <Border.Background>



   6:                             <LinearGradientBrush EndPoint="0.512,1.154" StartPoint="0.512,0.154">



   7:                                 <GradientStop Color="White" Offset="1"/>



   8:                                 <GradientStop Color="AntiqueWhite" Offset="0.339"/>



   9:                             </LinearGradientBrush>



  10:                         </Border.Background>



  11:                         <StackPanel Width="Auto" Background="Transparent">



  12:                             <TextBlock Text="No Records" Foreground="Red" ></TextBlock>



  13:                             <TextBlock Text="This template may be changed using XAML!!" Foreground="Red"></TextBlock>



  14:                         </StackPanel>



  15:                     </Border>



  16:                 </local:EmptyDataTemplate>



  17:             </local:DataGridWithEmptyTemplate.EmptyTemplate>



  18:         </local:DataGridWithEmptyTemplate>




image



Needless to say, the other functionality of datagrid remain the same as we have only introduced new DPs which have NO impact on existing functionality.



Finally here is the code.



Technorati Tags: ,