Everyone now and then you will run into a requirement for adding a footer row for a data grid. If you are not using a third party control, you could use two grids in a user control to achieve this. Top grid houses the data and bottom grid with one row which will listen to data change in the first grid and generate the summary row.
Recently the new version of Component One, you can get the footer row out of the box if you were using C1FlexGrid/C1FlexGridExcel. Lets see how can we use it to achieve adding a footer row. Lets start out the basic requirement for this example.
1. Display personal information in a Grid, need to display, Name, Age, Sex and Salary.
2. Display a footer row which includes total number of rows, average of Age and salary total.
Lets start out building Silverlight application. Since I am a big fan of design time data and I can get that out of box using Jounce, I am going to create a new Jounce Application.
Create Model first
public class Person : INotifyPropertyChanged
{
public string Name { get; set; }
public int Salary { get; set; }
public char Sex { get; set; }
public int Age { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
Make sure you modify the interface for View Model to get personal information (IMainViewModel.cs)
public interface IMainViewModel
{
List<Person> People { get; }
}
My design time data comes from the design viewmodel
public classDesignMainViewModel : IMainViewModel
{
publicList<Person> People
{
get
{
List<Person> ppl = newList<Person>();
ppl.Add(newPerson() { Name = "a", Age = 20, Salary = 1000, Sex = ‘f’ });
ppl.Add(newPerson() { Name = "b", Age = 21, Salary = 1100, Sex = ‘m’});
ppl.Add(newPerson() { Name = "c", Age = 22, Salary = 1200, Sex = ‘m’});
ppl.Add(newPerson() { Name = "d", Age = 23, Salary = 1300, Sex = ‘f’ });
ppl.Add(newPerson() { Name = "e", Age = 24, Salary = 1400, Sex = ‘f’ });
ppl.Add(newPerson() { Name = "f", Age = 25, Salary = 1500, Sex = ‘f’ });
ppl.Add(newPerson() { Name = "g", Age = 26, Salary = 1600, Sex = ‘m’});
ppl.Add(newPerson() { Name = "h", Age = 27, Salary = 1700, Sex = ‘m’});
ppl.Add(newPerson() { Name = "i", Age = 28, Salary = 1800, Sex = ‘f’ });
returnppl;
}
}
}
my runtime view model
[ExportAsViewModel("MainViewModel")]
public class MainViewModel : BaseViewModel, IMainViewModel
{
public List<Person> People
{
get
{
List<Person> ppl = new List<Person>();
ppl.Add(new Person() { Name = "a", Age = 20, Salary = 1000, Sex = 'f' });
ppl.Add(new Person() { Name = "b", Age = 21, Salary = 1100, Sex = 'm' });
ppl.Add(new Person() { Name = "c", Age = 25, Salary = 2100, Sex = 'f' });
ppl.Add(new Person() { Name = "d", Age = 27, Salary = 2100, Sex = 'f' });
return ppl;
}
}
}
Now we have data to load, lets look at the XAML
<c1:C1FlexGridExcel Name="flex" AutoGenerateColumns="False" ItemsSource="{Binding People}">
<c1:C1FlexGridExcel.Columns>
<c1:Column Binding="{Binding Name,Mode=OneWay}" GroupAggregate="Count"/>
<c1:Column Binding="{Binding Age, Mode=TwoWay}" GroupAggregate="Average"/>
<c1:Column Binding="{Binding Sex}"/>
<c1:Column Binding="{Binding Salary, Mode=TwoWay}" GroupAggregate="Sum"/>
</c1:C1FlexGridExcel.Columns>
</c1:C1FlexGridExcel>
If you notice, all I am doing is binding the column to display and also specifying what kind of aggregation we need to display in footer row. As per the requirement, we want to total number of personal so I added the group aggregate function as ‘Count’ and Average for Age and Sum for Salary. So my design time screen will look like the following
So far no footer row. In the current release, you can add the footer row in the code behind as follows
public MainPage()
{
InitializeComponent();
var gr = new C1.Silverlight.FlexGrid.GroupRow();
flex.ColumnFooters.Rows.Add(gr);
}
So to add a footer row, all you have to create a group row and add that as the ColumnFooter rows. With this change if you compile and run it
You can apply style, color and all the goodies you would do to any group row, you can do it here as well.
**** Update 8/5/11 *******
There is a support for design time data so you can do it in XAML itself rather than code behind, which I really like. We need to add ColumnFooterRows in the XAML that’s all about it. Modified XAML would be something like the following
<c1:C1FlexGridExcel Name="flex" AutoGenerateColumns="False" ItemsSource="{Binding People}">
<c1:C1FlexGridExcel.ColumnFooterRows>
<c1:GroupRow/>
</c1:C1FlexGridExcel.ColumnFooterRows>
<c1:C1FlexGridExcel.Columns>
<c1:Column Binding="{Binding Name,Mode=OneWay}" GroupAggregate="Count"/>
<c1:Column Binding="{Binding Age, Mode=TwoWay}" GroupAggregate="Average"/>
<c1:Column Binding="{Binding Sex}"/>
<c1:Column Binding="{Binding Salary, Mode=TwoWay}" GroupAggregate="Sum"/>
</c1:C1FlexGridExcel.Columns>
</c1:C1FlexGridExcel>
With this change now if you look at the design view you will see the footer row, you do not need to run the program to see it.