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

3 thoughts on “Empty Data template in Silverlight DataGrid

  1. Hi Pushpak,

    I’m Ganesh from Nomura Services India Pvt Ltd, Mumbai. We are currently looking for a silverlight resource with close to 4-5 years experience and good knowledge in .net 3.5 and WPF/Silverlight for my team in Mumbai.

    Please feel to share any profiles you know of, who you think would fit my requirement.

    Keep up the good work!

    Cheers!
    Ganesh

    Like

  2. This is a great idea, and offered a great starting point for me. However this isn’t too great for binding.

    It does not update the datagrid when itemsource is changed, I moved the Loaded code to a PropertyChangedCallback on a new ItemsSource property on the DataGridWithEmptyTemplate.

    It does not restore the datagrid if the itemsource is changed to something with a value. This is fixed by checking if the count is something other than 0 and the EmptyDataTemplate exists in the columns, then restoring the datagrid.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s