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.
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>
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.
No comments:
Post a Comment