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: ,

No comments: