Introduction

Chart love

Just noticed that Microsoft have released a free Chart control for ASP .NET and Winforms. Totally cool.

Read more about it at Scott Gurthries blog.

Here is a small screen shot to wet your appetite

charts.png

This is a nice thing of Microsoft to do, this is very very cool indeed.

Advertisements
C#, CodeProject, Current Work, Employment, WCF, WPF

How To Create A WCF Client Proxy Without Having a Deployed WCF Service

At work we are currently using a very very Agile process, which involves 1/4 hourly builds, which was all going brilliantly with a WPF solution and some Mocks and some NUnit test projects. Then we got to the point where we had to start building our WCF service and have the WPF project obtain a new service reference client proxy based on the newly built WCF service project. This is easily achieved using NANT and wiring up dependencies in a NANT script, but we were not in a position where we could actual deploy the WCF Service with every build, due to the fact that we are hosting the WCF service inside a Windows service.

We could have also automated this using InstallUtil.exe to install the service, but this would have added more complexity to an already complex build arrangement within our CI build server AKA “Cruise Control”. We could have done it, but we simply wanted to be able to create a new service reference client proxy. Normally what one would do would be to add a service reference within Visual Studio, something like the figure shown below:

ServiceReference

When you add a service reference using Visual Studio, you typically have to have, the service both deployed and running, and you then point the wizard at the deployed and running service address, which exposes some metadata which allows the wizard to be able to see information about the service. This will then create a bunch of items in Visual Studio, such as the following :

ref

One of the these generated files is the service reference client proxy. In this case it is called “Reference.cs”, which if we examine a small section of it, contains all the DataContract / ServiceContract class definitions.

dc

Which is fine, but as I stated above, what was needed for a continuous build environment (Cruise Control) was the ability to create this service reference client proxy class “Reference.cs” without a deployed service. Mmmm, how could we do that.

Well luckily there is a command line tool which can be run as part of a NANT script. This utility is called “svcutil.exe”, and has many options, which you can find using the svcutil.exe /? switch.

But to help you out here is what we had to do in order to duplicate the functionality provided by the Visual Studio wizard using just svcutil.exe.

It was a 2 phase operation, the phases are as follows:

Create WSDL from Dlls

You can create a WSDL by using the Dlls themselves, and then you can use the WSDL to create a service reference client proxy class. Here is how we did this.

Switch Description
/d: /d:<directory> Directory to create files in (default: current directory)
/reference: /reference:<file path> : Add the specified assembly to the set of assemblies used for resolving type references.

svcutil /directory:c:SOMEDIRECTORY “<SERVICE CONTRACT DLL PATH>”
/reference:”<DATACONTRACT DLL PATH>”

NOTE : You may have all your ServiceContract and DataContract classes all in one Dll, so in this case you would not need the /reference: switch, this is only need to link in additional Dlls.

Use WSDL to create WPF client service reference proxy class

Once we had a WSDL we could the use this to create the create a service reference client proxy class. We did this as follows:

Switch Description
/d: /d:<directory> Directory to create files in (default: current directory)
/l: Language C# or VB
/out: Name of output file
/noconfig Do not generate a client layer App.Config file
/s /serializable : Generate classes marked with the Serializable Attribute
/ct /collectionType: <type> : A fully-qualified or assembly-qualified name of the type to use as a collection data type when code is generated from schemas.
/ser: /serializer: Auto – Automatically select the serializer. This tries to use the Data Contract serializer and uses the XmlSerializer if that fails.
/tcv: /targetClientVersion:Version35 : Generate code that references functionality in .NET Framework assemblies 3.5 and before.
/n: /namespace:<string,string> : A mapping from a WSDL or XML Schema targetNamespace to a CLR namespace.
/edb /enableDataBinding : Implement the System.ComponentModel.INotifyPropertyChanged interface on all Data Contract types to enable data binding.

svcutil
/d:c:SOMEDIRECTORY
c:SOMEDIRECTORY*.wsdl c:SOMEDIRECTORY*.xsd
/l:C#
/out:Reference.cs
/noconfig
/s
/ct:System.Collections.Generic.List`1
/ser:Auto
/tcv:Version35
/n:*,<THE NAMESPACE TO USE>
/edb

And that was enough for us to generate a new WPF client service reference proxy class in an automated manner, without the need to have the WCF service deployed and running.

Hope this helps someone out there

Beginners Guide To Threading, CodeProject, Lambdas / Anonomous delegates, WPF

NUnit STA Threads & Testing WPF

During the course of the WPF project we are working on at work, we decided to go down the Agile/XP/TDD/Mocks/Continuous Integration route, which means Unit tests, lots of them.

We are using NUnit, which I really like, but we are also using WPF, we are obviously using the latest/greatest patterns AKA MVVM, but from time tom time it is nice to be able to test certain things on WPF controls/windows etc etc.

So I set out to create a small NUnit test like the following:


/* Style Definitions */ table.MsoNormalTable {mso-style-name:”Table Normal”; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:”Times New Roman”; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi;}

diag11.jpg
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Now to me this looked fine, but when I ran this code I got the following horror show.

STAThread

Where NUnit moaned about “The calling thread must be STA”. Oh, that’s to bad. So I had a small think, and then came up with this small idea, just pass the original code to a helper class and have it run that in a Thread using STA threading apartment state. Sounds cool, but did it work. Well yes actually it did, and here is the small helper class.

 

 diag2.jpg


.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }And here is how to use this from a NUnit test.


/* Style Definitions */ table.MsoNormalTable {mso-style-name:”Table Normal”; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:”Times New Roman”; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi;}

diag3.jpg

And just to prove it works, here is a screen shot of the actual test running successfully.

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }STAThreadOK

Here is a link to a small test project that you can see this working with : wpfandnunittest1.zip in case you want to use this in your own projects.

Enjoy

LINQ

A Journey Into Expressions

I have been a little obsessed with LINQ and Func<T,TResult> of late and finally managed to find some time to do a little bit of exploration into the System.Linq.Expressions namespace.

I have published an article over at codeproject (http://www.codeproject.com/KB/linq/Expressions.aspx) which tells you all about how to create the following

lamda expression : (x) => x.Length > 1 , entirely in code using the System.Linq.Expressions namespace.

In case you are curious this is what this expression looks like when working with the System.Linq.Expressions namespace:

 

   1:  ConstantExpression constLength = Expression.Constant(1);
   2:   
   3:  ParameterExpression stringParameter = 
   4:      Expression.Parameter(typeof(String), "s");
   5:   
   6:  MemberExpression stringMember = 
   7:      LambdaExpression.PropertyOrField(stringParameter, "Length");
   8:   
   9:   
  10:  Expression<Func<String, Boolean>> bindLambda =
  11:      Expression.Lambda<Func<String, Boolean>>
  12:      (
  13:          Expression.GreaterThan(
  14:          stringMember,
  15:          constLength),
  16:          stringParameter
  17:      );
  18:   
  19:   
  20:  foreach (String bindingString in 
  21:      bindings.Where(bindLambda.Compile()))
  22:  {
  23:     .....
  24:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

In the article I obvisouly talk in a lot more detail, so if you want to know more, just have a look at the full article http://www.codeproject.com/KB/linq/Expressions.aspx

CodeProject, WPF

xamDataGrid RecordsFound Adorner

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>

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }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:          }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }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:          /// <summary>
  36:          /// RecordCount Dependency Property
  37:          /// </summary>
  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:          /// <summary>
  45:          /// Gets or sets the RecordCount property.  
  46:          /// </summary>
  47:          public Int32 RecordCount
  48:          {
  49:              get { return (Int32)GetValue(RecordCountProperty); }
  50:              set { SetValue(RecordCountProperty, value); }
  51:          }
  52:  
  53:          /// <summary>
  54:          /// Handles changes to the RecordCount property.
  55:          /// </summary>
  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:  }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }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:      /// <summary>
  12:      /// Hosts an single Label in the AdornerLayer
  13:      /// </summary>
  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:          /// <summary>
  52:          /// Allows the control to determine how big it wants to be.
  53:          /// </summary>
  54:          /// <param name="constraint">A limiting size for the control.</param>
  55:          protected override Size
  56:              MeasureOverride(Size constraint)
  57:          {
  58:              return constraint;
  59:          }
  60:  
  61:          /// <summary>
  62:          /// Positions and sizes the control.
  63:          /// </summary>
  64:          /// <param name="finalSize">The actual size of the control.</param>        
  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:          /// <summary>
  79:          /// Required for the element to be rendered.
  80:          /// </summary>
  81:          protected override int VisualChildrenCount
  82:          {
  83:              get { return 1; }
  84:          }
  85:  
  86:          /// <summary>
  87:          /// Required for the element to be rendered.
  88:          /// </summary>
  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:          /// <summary>
 102:          /// Required for the displayed element to 
 103:          /// inherit property values
 104:          /// from the logical tree, such as FontSize.
 105:          /// </summary>
 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:  }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Here are some screen shots showing this code in action, with some records within the xamDataGrid we see no label

xamGrid1

With 0 records within the xamDataGrid we see a label

xamGrid2

And finally here is the source code xamdatagridrecordsadorner.zip