Click here to Skip to main content
11,704,472 members (58,571 online)
Click here to Skip to main content

Tagged as

xamDataGrid RecordsFound Adorner

, 17 Jun 2009 CPOL 14.7K 103 6
Rate this:
Please Sign up or sign in to vote.
At work we are using the Infragistics .NET Advantage For WPF, one control of which is the xamDataGrid. We had a small requirement that was to show a label over the grid whenever no records were obtained for the xamDataGrid.DataSource.Now I could have tackled this in a simple manner where I placed t

At work we are using the Infragistics .NET Advantage For WPF, one control of which is the xamDataGrid. We had a small requirement that was to show a label over the grid whenever no records were obtained for the xamDataGrid.DataSource.

Now I could have tackled this in a simple manner where I placed the xamDataGrid in a Grid along with a Label both with Margin=”0″, and both with HorizontalAlignment=”Stretch” and VerticalAlignment=”Stretch”, and then set the label visibility either in code behind or using a special ValueConverter. But where would be the fun/elegance in that.

So what I decided to do was create a special AdornerDecorator and a special Adorner to do the job.

The AdornerDecorator (DataGridRecordAdornerDecorator) that I wrote allows you to bind a RecordCount DependencyProperty to the source xamDataGrid.Records.Count , and from there the DataGridRecordAdornerDecorator is self managing, and will either show a message (which can be set via the Prompt CLR property).

Its fairly easy to setup here is the most important part of the xaml for the Window that contains the xamDataGrid

 1:          <Grid Background=”Gray” Margin=”0″>
 2:              <igDP:XamDataGrid x:Name=”XamDataGrid1″
 3:                                Theme=”Onyx”
 4:                                Margin=”0″
 5:                                HorizontalAlignment=”Stretch”
 6:                                VerticalAlignment=”Stretch”
 7:                                DataSource=
 8:                                “{Binding
 9:                                Source={StaticResource
10:                                BookData},XPath=Book}”>
11:              </igDP:XamDataGrid>
12:
13:              <local:DataGridRecordAdornerDecorator
14:                  Prompt=”GRRR, Why no stuff”
15:                  RecordCount=”{Binding
16:                  ElementName=XamDataGrid1,
17:                  Path=Records.Count}”/>
18:
19:          </Grid>

Where I am simply toggling the DataSource to a small xml data island or to null, in code behind. Here is the code to do this, this is just test code, you SHOULD NOT use this code, it is just to demonstrate the attached demo app.

 1:          private void btnToggle_Click(object sender, RoutedEventArgs e)
 2:          {
 3:              if (zeroTheDataSource)
 4:              {
 5:                  XamDataGrid1.DataSource = null;
 6:              }
 7:              else
 8:              {
 9:                  Binding b = new Binding();
10:                  b.Source = this.TryFindResource(“BookData”)
11:                      as XmlDataProvider;
12:                  b.XPath = “Book”;
13:                  XamDataGrid1.SetBinding(
14:                      XamDataGrid.DataSourceProperty, b);
15:              }
16:              zeroTheDataSource = !zeroTheDataSource;
17:              MessageBox.Show(XamDataGrid1.
                 Records.Count.ToString());
18:
19:          }

So how does the DataGridRecordAdornerDecorator work, well its actually very simple. It simply shows/hides a specialized Adorner (DataGridRecordAdorner) based on the current value of the RecordCount DependencyProperty. Here is the code

  1:  using System;
  2:  using System.Windows;
  3:  using System.Windows.Documents;
  4:
  5:  namespace WpfApplication1
  6:  {
  7:      public class DataGridRecordAdornerDecorator
              : AdornerDecorator
  8:      {
  9:          #region Data
 10:          private AdornerLayer layer = null;
 11:          private DataGridRecordAdorner adorner = null;
 12:          private FrameworkElement adornedElement;
 13:          private String prompt = “No RECORDS FOUND”;
 14:          #endregion
 15:
 16:          #region Ctor
 17:          public DataGridRecordAdornerDecorator()
 18:          {
 19:              this.Loaded +=
 20:                  new RoutedEventHandler(
 21:                      DataGridRecordAdornerDecorator_Loaded);
 22:          }
 23:          #endregion
 24:
 25:          #region Public Properties
 26:
 27:
 28:          public String Prompt
 29:          {
 30:              get { return prompt;}
 31:              set { prompt = value;}
 32:          }
 33:
 34:
 35:          /// <span class="code-SummaryComment"><summary></span>
 36:          /// RecordCount Dependency Property
 37:          /// <span class="code-SummaryComment"></summary></span>
 38:          public static readonly DependencyProperty RecordCountProperty =
 39:              DependencyProperty.Register(“RecordCount”, typeof(Int32),
 40:                  typeof(DataGridRecordAdornerDecorator),
 41:                      new FrameworkPropertyMetadata((Int32)0,
 42:                      new PropertyChangedCallback(OnRecordCountChanged)));
 43:
 44:          /// <span class="code-SummaryComment"><summary></span>
 45:          /// Gets or sets the RecordCount property.  
 46:          /// <span class="code-SummaryComment"></summary></span>
 47:          public Int32 RecordCount
 48:          {
 49:              get { return (Int32)GetValue(RecordCountProperty); }
 50:              set { SetValue(RecordCountProperty, value); }
 51:          }
 52:
 53:          /// <span class="code-SummaryComment"><summary></span>
 54:          /// Handles changes to the RecordCount property.
 55:          /// <span class="code-SummaryComment"></summary></span>
 56:          private static void OnRecordCountChanged(DependencyObject d,
 57:              DependencyPropertyChangedEventArgs e)
 58:          {
 59:              DataGridRecordAdornerDecorator me =
 60:                  (DataGridRecordAdornerDecorator)d;
 61:
 62:              Int32 value = 0;
 63:              Int32.TryParse(e.NewValue.ToString(), out value);
 64:
 65:              if (value == 0)
 66:              {
 67:                  me.adorner = new DataGridRecordAdorner(
 68:                      me.adornedElement, me.Prompt);
 69:                  me.layer.Add(me.adorner);
 70:              }
 71:              else
 72:              {
 73:                  if (me.adorner != null &&
 74:                      me.layer != null)
 75:                  {
 76:                      me.layer.Remove(me.adorner);
 77:                      me.adorner = null;
 78:                  }
 79:              }
 80:          }
 81:          #endregion
 82:
 83:          #region Private Methods
 84:
 85:          private void DataGridRecordAdornerDecorator_Loaded(
 86:              object sender, RoutedEventArgs e)
 87:          {
 88:              layer = this.AdornerLayer;
 89:              adornedElement = new FrameworkElement {
 90:                  Height = this.Height, Width = this.Width };
 91:              this.Child = adornedElement;
 92:
 93:
 94:          }
 95:          #endregion
 96:
 97:          #region Overrides
 98:          protected override void OnRenderSizeChanged(
 99:              System.Windows.SizeChangedInfo sizeInfo)
100:          {
101:              base.OnRenderSizeChanged(sizeInfo);
102:
103:              if (adornedElement != null)
104:              {
105:                  adornedElement.Height = sizeInfo.NewSize.Height;
106:                  adornedElement.Width = sizeInfo.NewSize.Width;
107:              }
108:
109:          }
110:          #endregion
111:      }
112:  }

And here is the code for the DataGridRecordAdorner.

  1:  using System;
  2:  using System.Collections;
  3:  using System.Windows;
  4:  using System.Windows.Controls;
  5:  using System.Windows.Documents;
  6:  using System.Windows.Media;
  7:  using System.Collections.ObjectModel;
  8:
  9:  namespace WpfApplication1
 10:  {
 11:      /// <span class="code-SummaryComment"><summary></span>
 12:      /// Hosts an single Label in the AdornerLayer
 13:      /// <span class="code-SummaryComment"></summary></span>
 14:      public class DataGridRecordAdorner : Adorner
 15:      {
 16:          #region Data
 17:          private ArrayList logicalChildren;
 18:          private readonly Grid host = new Grid();
 19:          #endregion // Data
 20:
 21:          #region Constructor
 22:
 23:
 24:
 25:          public DataGridRecordAdorner(
 26:              FrameworkElement adornedCtrl, String prompt)
 27:              : base(adornedCtrl)
 28:          {
 29:
 30:              host.Width = (double)adornedCtrl.ActualWidth;
 31:              host.Height = (double)adornedCtrl.ActualHeight;
 32:              host.VerticalAlignment = VerticalAlignment.Center;
 33:              host.HorizontalAlignment = HorizontalAlignment.Center;
 34:              host.Margin = new Thickness(0);
 35:              Label lbl = new Label();
 36:              lbl.Content = prompt;
 37:              lbl.Foreground = Brushes.White;
 38:              lbl.FontSize = 14;
 39:              lbl.FontWeight = FontWeights.Bold;
 40:              lbl.VerticalAlignment = VerticalAlignment.Center;
 41:              lbl.HorizontalAlignment = HorizontalAlignment.Center;
 42:              lbl.Margin = new Thickness(0);
 43:              host.Children.Add(lbl);
 44:              base.AddLogicalChild(host);
 45:              base.AddVisualChild(host);
 46:          }
 47:          #endregion // Constructor
 48:
 49:          #region Measure/Arrange
 50:
 51:          /// <span class="code-SummaryComment"><summary></span>
 52:          /// Allows the control to determine how big it wants to be.
 53:          /// <span class="code-SummaryComment"></summary></span>
 54:          /// <span class="code-SummaryComment"><param name=”constraint”>A limiting size for the control.</param></span>
 55:          protected override Size
 56:              MeasureOverride(Size constraint)
 57:          {
 58:              return constraint;
 59:          }
 60:
 61:          /// <span class="code-SummaryComment"><summary></span>
 62:          /// Positions and sizes the control.
 63:          /// <span class="code-SummaryComment"></summary></span>
 64:          /// <span class="code-SummaryComment"><param name=”finalSize”>The actual size of the control.</param>        </span>
 65:          protected override Size
 66:              ArrangeOverride(Size finalSize)
 67:          {
 68:              Rect rect = new Rect(new Point(), finalSize);
 69:
 70:              host.Arrange(rect);
 71:              return finalSize;
 72:          }
 73:
 74:          #endregion // Measure/Arrange
 75:
 76:          #region Visual Children
 77:
 78:          /// <span class="code-SummaryComment"><summary></span>
 79:          /// Required for the element to be rendered.
 80:          /// <span class="code-SummaryComment"></summary></span>
 81:          protected override int VisualChildrenCount
 82:          {
 83:              get { return 1; }
 84:          }
 85:
 86:          /// <span class="code-SummaryComment"><summary></span>
 87:          /// Required for the element to be rendered.
 88:          /// <span class="code-SummaryComment"></summary></span>
 89:          protected override Visual GetVisualChild(int index)
 90:          {
 91:              if (index != 0)
 92:                  throw new ArgumentOutOfRangeException(“index”);
 93:
 94:              return host;
 95:          }
 96:
 97:          #endregion // Visual Children
 98:
 99:          #region Logical Children
100:
101:          /// <span class="code-SummaryComment"><summary></span>
102:          /// Required for the displayed element to 
103:          /// inherit property values
104:          /// from the logical tree, such as FontSize.
105:          /// <span class="code-SummaryComment"></summary></span>
106:          protected override IEnumerator LogicalChildren
107:          {
108:              get
109:              {
110:                  if (logicalChildren == null)
111:                  {
112:                      logicalChildren = new ArrayList();
113:                      logicalChildren.Add(host);
114:                  }
115:
116:                  return logicalChildren.GetEnumerator();
117:              }
118:          }
119:
120:          #endregion // Logical Children
121:      }
122:  }

Here are some screen shots showing this code in action, with some records within the xamDataGrid we see no label

xamgrid1-thumb.jpg

With 0 records within the xamDataGrid we see a label

xamgrid2-thumb.jpg

And finally here is the source code xamdatagridrecordsadorner.zip - 1.6 MB

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sacha Barber
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150819.1 | Last Updated 17 Jun 2009
Article Copyright 2009 by Sacha Barber
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid