Empty data template in RadGridView for Silverlight (and WPF)

Monday, February 01, 2010 by Pavel Pavlov | Comments 20

One more RadGridView behavior frequently requested by our clients is to display a message when there are no records to display. A typical real life scenario would be a RadGridView displaying a list of search results. When there are no results found we would like to have a message like “No results found!” displayed in RadGridView.

 

noresults

 

 

If you download the project above , you will see that if you get the EmptyDataTemplateBehavior.cs into your project, setting the empty data template will be as easy as writing a few lines of XAML :

<telerik:RadGridView x:Name="RadGridView1" >
			<i:Interaction.Behaviors>
				<local:EmptyDataTemplateBehavior>
					<local:EmptyDataTemplateBehavior.EmptyDataTemplate>
						<DataTemplate>
							<TextBlock Text="No results found!" Foreground="White"  HorizontalAlignment="Center"  VerticalAlignment="Center" Visibility="{Binding MessageVisibility}" />
						</DataTemplate>
					</local:EmptyDataTemplateBehavior.EmptyDataTemplate>
				</local:EmptyDataTemplateBehavior>
			</i:Interaction.Behaviors>
		</telerik:RadGridView>

 

*As you may know from my previous posts concerning attached behaviors , you will need  to add a reference to the System.Windows.Interactivity.dll.

*As always the same approach is applicable for the WPF version of RadGridView provided that you reference the right version of the System.Windows.Interactivity.dll.

20 Comments

  • Fredrik Lundberg 11 Feb 2010
    I get an:
    ArgumentOutOfBoundsException

    on the row:

    Grid

     

     

    rootGrid = gridView.ChildrenOfType<Grid>()[1];

     

    in EmptyDataTemplateBehavior

    And if I catch it I don't get the "No result found" text
  • Priya 08 Mar 2010
    Hello,

    Any solution on 'ArgumentOutOfBoundsException' ??
  • Ralph 16 Mar 2010

    The function containing the ChildrenOfType line is called twice. The first time there are no children of type Grid.

    Changing the function to the following solves the problem and displays the empty message, but I can't explain why. Perhaps someone of telerik can post the correct solution.

     

    private

     

    void LoadTemplateIntoGridView(RadGridView gridView)

     

    {

     

    contentPresenter.IsHitTestVisible =

    false;

     

    contentPresenter.DataContext =

    this;

     

    contentPresenter.ContentTemplate =

    this.EmptyDataTemplate;

     

     

    if (gridView.ChildrenOfType<Grid>().Count > 0)

     

    {

     

    Grid rootGrid = gridView.ChildrenOfType<Grid>()[1];

     

    contentPresenter.SetValue(

    Grid.RowProperty, 2);

     

    contentPresenter.SetValue(

    Grid.RowSpanProperty, 2);

     

    contentPresenter.SetValue(

    Grid.ColumnSpanProperty, 2);

     

    contentPresenter.SetValue(

    Border.MarginProperty, new Thickness(0, 27, 0, 0));

     

    rootGrid.Children.Add(contentPresenter);

    }

    }

  • Greg 18 Mar 2010
    I cannot load the solution. I get: The imported project  "C:\Program Files\...\Microsoft.CSharp.targets" was not found.
  • Karlkim 09 Apr 2010
    Could you an example of how to add this behavior using code-behind?

    Thanks,
    Karlkim
  • Chris Helmeset 20 May 2010
    This was a wonderful post.  I have it working just fine.  My only problem is when I try to bind directly to the text instead of hard coding.  I have several different scenarios in which there may be no results.  For example, no user access to the requested data or just no data but I would like to display specific messages under the specific conditions.  When trying to bind it fails to display any message at all.  No exceptions are thrown just no message.  Any ideas would be appreciated.

    Thanks,
    Chris H.
  • GC 26 May 2010
    Hi,
    Thanks a lot for this great post, but I would also love to hear how you can make the message a bit more dynamic !

    Guillaume
  • GC 26 May 2010
    Hi,
    Thanks a lot for this great post, but I would also love to hear how you can make the message a bit more dynamic !

    Guillaume
  • Rami 13 Aug 2010
    Thank you Pavel,

    This seems to be broken with RadControls_for_Silverlight 2010_2_0812.

    Have there been any updates since the original post to resolve this isuse and the other issue previously reported in the comments section of this post?

    Thank you.
  • Prakash 17 Nov 2010
    Can i have custom No Records Text using some property for the Grid... if so please provide me a sample..
  • M.rkino 24 Mar 2011
    It seems the code doesnt work using new realease of RadGridView as Rami wrote. How fix?







    M.
  • M.rkino 24 Mar 2011
    It seems the code doesnt work using new realease of RadGridView as Rami wrote. How fix?







    M.
  • Anurag 15 Apr 2011
    When i run the above code it dosent work(not showing No Data Found)can anyone tell me what is the reason behind it?
  • James R 05 May 2011
    Mmm.. ok this is waaay to complicated for a Software suite we pay for. And it doesn't really work...
  • Dean 06 May 2011
    Karlkim

    Here is a behaviour class that does it all in code:
      public class EmptyDataTemplateBehavior : Behavior<RadGridView>
      {
        ContentPresenter contentPresenter = new ContentPresenter();
      
        public EmptyDataTemplateBehavior()
        {
        }
      
        public EmptyDataTemplateBehavior(RadGridView grid)
        {
          Attach(grid);
        }
      
        public void Attach(RadGridView grid)
        {
          System.Windows.Interactivity.Interaction.GetBehaviors(grid).Add(this);
        }
      
        protected override void OnAttached()
        {
          EmptyDataTemplate = (DataTemplate)XamlReader.Load(
         <TextBlock Text=""No Matching Records Found."" HorizontalAlignment=""Center""  VerticalAlignment=""Center"" />
    </DataTemplate>"); //Visibility=""{Binding MessageVisibility}""
          base.OnAttached();
          this.AssociatedObject.LayoutUpdated += new EventHandler(AssociatedObject_LayoutUpdated);
        }
      
        public DataTemplate EmptyDataTemplate { get; set; }
      
        void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
        {
          Grid rootGrid = this.AssociatedObject.ChildrenOfType<Grid>().FirstOrDefault();
      
          if (rootGrid != null)
          {
            this.AssociatedObject.LayoutUpdated -= new EventHandler(AssociatedObject_LayoutUpdated);
            this.LoadTemplateIntoGridView(this.AssociatedObject);
            this.AssociatedObject.Items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Items_CollectionChanged);
            SetVisibility();
          }
        }
      
        void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
          SetVisibility();
        }
      
        private void SetVisibility()
        {
          if (this.AssociatedObject.Items.Count == 0)
            this.contentPresenter.Visibility = Visibility.Visible;
          else
            this.contentPresenter.Visibility = Visibility.Collapsed;
        }
      
        private void LoadTemplateIntoGridView(RadGridView gridView)
        {
      
          contentPresenter.IsHitTestVisible = false;
          contentPresenter.DataContext = this;
          contentPresenter.ContentTemplate = EmptyDataTemplate;
          Grid rootGrid = gridView.ChildrenOfType<Grid>()[0];
      
          contentPresenter.SetValue(Grid.RowProperty, 2);
          contentPresenter.SetValue(Grid.RowSpanProperty, 2);
          contentPresenter.SetValue(Grid.ColumnSpanProperty, 2);
          contentPresenter.SetValue(Border.MarginProperty, new Thickness(0, 27, 0, 0));
          rootGrid.Children.Add(contentPresenter);
        }
      }

    Somewhere in your code:
            EmptyDataTemplateBehavior EDTB = new EmptyDataTemplateBehavior(grid);

    Or:
            EmptyDataTemplateBehavior EDTB = new EmptyDataTemplateBehavior();
    EDTB.Attach(grid);


    Now, I do not use Behaviors, so, I decided to make an EmptyDataTemplate without all of this behavior overhead;

      public class RadGridEmptyDataTemplate
      {
        ContentPresenter _contentPresenter = new ContentPresenter();
        RadGridView _grid = null;
      
        public RadGridEmptyDataTemplate()
        {
        }
      
        public RadGridEmptyDataTemplate(RadGridView grid)
        {
          Attach(grid);
        }
      
        public void Attach(RadGridView grid)
        {
          _grid = grid;
          EmptyDataTemplate = (DataTemplate)XamlReader.Load(
         <TextBlock Text=""No Matching Records Found."" HorizontalAlignment=""Center""  VerticalAlignment=""Center"" />
    </DataTemplate>"); 
          grid.LayoutUpdated += new EventHandler(grid_LayoutUpdated);
        }
      
        void grid_LayoutUpdated(object sender, EventArgs e)
        {
          if (_grid != null)
          {
            Grid rootGrid = _grid.ChildrenOfType<Grid>().FirstOrDefault();
      
            if (rootGrid != null)
            {
              _grid.LayoutUpdated -= new EventHandler(grid_LayoutUpdated);
              LoadTemplateIntoGridView();
              _grid.Items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Items_CollectionChanged);
              SetVisibility();
            }
          }
        }
      
        public DataTemplate EmptyDataTemplate { get; set; }
      
      
        void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
          SetVisibility();
        }
      
        private void SetVisibility()
        {
          if (_grid != null)
          {
            if (_grid.Items.Count == 0)
              this._contentPresenter.Visibility = Visibility.Visible;
            else
              this._contentPresenter.Visibility = Visibility.Collapsed;
          }
        }
      
        private void LoadTemplateIntoGridView()
        {
      
          _contentPresenter.IsHitTestVisible = false;
          _contentPresenter.DataContext = this;
          _contentPresenter.ContentTemplate = EmptyDataTemplate;
          Grid rootGrid = _grid.ChildrenOfType<Grid>()[0];
      
          _contentPresenter.SetValue(Grid.RowProperty, 2);
          _contentPresenter.SetValue(Grid.RowSpanProperty, 2);
          _contentPresenter.SetValue(Grid.ColumnSpanProperty, 2);
          _contentPresenter.SetValue(Border.MarginProperty, new Thickness(0, 27, 0, 0));
          rootGrid.Children.Add(_contentPresenter);
        }
      }
      
    Then, somewhere in your code:
      
    RadGridEmptyDataTemplate EDT = new RadGridEmptyDataTemplate(grid);
      
    or 
    RadGridEmptyDataTemplate EDT = new RadGridEmptyDataTemplate();
    EDT.Attach(grid);

    The EmptyDataTemplate property defaults to "No Matching Records Found.", but you can set it to anything you like after construction (and/or remove or change the default).
  • Dean 11 May 2011
    Still not satisfied, I decided that I would code this as a DependencyProperty / Attached Property. If anyone wants the code, it is posted in a reply to the issue at
    http://www.telerik.com/community/forums/silverlight/gridview/emptydatatemplate-radgridview.aspx



  • Mikhail 10 Nov 2011
    Awesome thank you Pavel!
  • sandeep 26 Jan 2012
    thnks a lot for posting this post.
  • sandy 27 Jan 2012
    Hi ,i have to apply this empty datatemplate to multiple grids in tab control.Am added the behavior to other grids.but am getting for first grid only. am tried for several ways . those r
    Am added this behavior to each grid.
    but am not getting for others.
    am getting for first grid only.
    Am also taken one same behaviour class and rename it as behaviour1.cs.
    Am added the name space for behaviour1.cs file also.
    still not getting.Here is sample code am sending with two behaviours.
    am writed same behaviour.cs file  for anothere grid also , but am getting that one also for 1 grid only.
    Pls help me.
    <i:Interaction.Behaviors>
                                <app:EmptyDataTemplateBehavior>
                                    <app:EmptyDataTemplateBehavior.EmptyDataTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="No DataFound." Foreground="Gray" HorizontalAlignment="Center"FontWeight="Bold"  VerticalAlignment="Center" />
                                        </DataTemplate>
                                    </app:EmptyDataTemplateBehavior.EmptyDataTemplate>
                                </app:EmptyDataTemplateBehavior>
                            </i:Interaction.Behaviors>
    <i1:Interaction.Behaviors>
                                <app1:EmptyDataTemplateBehavior1>
                                    <app1:EmptyDataTemplateBehavior1.EmptyDataTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="No DataFound." Foreground="Gray" HorizontalAlignment="Center"FontWeight="Bold"  VerticalAlignment="Center" />
                                        </DataTemplate>
                                    </app1:EmptyDataTemplateBehavior1.EmptyDataTemplate>
                                </app1:EmptyDataTemplateBehavior1>
                            </i1:Interaction.Behaviors>
    Thsnks in advance
  • Victor 19 Mar 2012
    This is totally broke in the latest release of radgrid. WHY do you always break your API with every release? At a minimum, come back to this page and tell us there is an updated page at a new location, or "sorry this is now absolete" so we don't waste time finding out it will not work. Just to be clear I'm talking about the 2012 Q1 release of radgrid and the Associated obect in EmptyDataTemplateBehavior.cs - did you really have to change this?

Add comment

  1. Formatting options
       
     
     
     
     
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)