DataGridView footer

  • Thread starter Thread starter Vanessa
  • Start date Start date
Vanessa,

You can't. You would have to custom paint the control and add the
footer (no small task, by any means). You are better off with a third-party
control that does this, or create your own control which will be displayed
below the DataGridView.
 
Thank you!

Well, what I need is to sum some columns and put the total in the last row.
If I add a row with the total, how can I prevent it to not participate in the
sort?

Thanks in advance!
Vanessa

Nicholas Paldino said:
Vanessa,

You can't. You would have to custom paint the control and add the
footer (no small task, by any means). You are better off with a third-party
control that does this, or create your own control which will be displayed
below the DataGridView.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Vanessa said:
Hi all,

How can I display a footer in a DataGridView?

Thank you in advance,
Vanessa
 
Hi,


Why don't you create a control that contain a grid and a couple of textboxes
under the correct column. Unless that you allow to reorder the columns in
the grid it should be relatively simple to do.

--
Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
Vanessa said:
Thank you!

Well, what I need is to sum some columns and put the total in the last
row.
If I add a row with the total, how can I prevent it to not participate in
the
sort?

Thanks in advance!
Vanessa

Nicholas Paldino said:
Vanessa,

You can't. You would have to custom paint the control and add the
footer (no small task, by any means). You are better off with a
third-party
control that does this, or create your own control which will be
displayed
below the DataGridView.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Vanessa said:
Hi all,

How can I display a footer in a DataGridView?

Thank you in advance,
Vanessa
 
Hello Ignacio,

Thank you for your answer.
That is the exact problem, my datagridview could reorder and hide some
columns.

What I need is something like this, but for windows form:
http://www.eggheadcafe.com/tutorial...33-1248becf3e16/sumcolumn-custom-datagri.aspx

Thanks in advance,
Vanessa

Ignacio Machin ( .NET/ C# MVP ) said:
Hi,


Why don't you create a control that contain a grid and a couple of textboxes
under the correct column. Unless that you allow to reorder the columns in
the grid it should be relatively simple to do.

--
Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
Vanessa said:
Thank you!

Well, what I need is to sum some columns and put the total in the last
row.
If I add a row with the total, how can I prevent it to not participate in
the
sort?

Thanks in advance!
Vanessa

Nicholas Paldino said:
Vanessa,

You can't. You would have to custom paint the control and add the
footer (no small task, by any means). You are better off with a
third-party
control that does this, or create your own control which will be
displayed
below the DataGridView.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi all,

How can I display a footer in a DataGridView?

Thank you in advance,
Vanessa
 
Hi all,

How can I display a footer in a DataGridView?

Thank you in advance,
Vanessa


Painting it is your best bet. I extended a ListView control to have a
footer and header. The footer was a summation of records as well as
the controls to allow for paging large records.

cheers
Greg
 
How are you putting the data in the DataGridView? Are you binding to
an existing list? If so, you might be able to influence the sort
behavior by providing a custom sort implementation. If this is a
DataTable it would be harder...

Marc
 
Damn; that makes this a pain... I'll see if I can come up with
something later? (busy at the mo...)

Marc
 
I got something working by having a dummy (hidden) column to indicate
whether it is a footer row or not (well, actually it just uses a
hidden preliminary sort, so it would also work for headers etc)...
It works by hiding an extra (first) sort in IBindingList and
IBindingListView... it has to be hidden for the reversal to work
properly.
here is the usage example; I'll post the implementation
(CustomDataView) in a second post (it's a bit long... but most of it
was auto-generated)

static void Main() {
Application.EnableVisualStyles();
// declare table
DataTable dt = new DataTable("Test");
dt.Columns.Add("IsFooter", typeof(bool));
dt.Columns.Add("Caption", typeof(string));
dt.Columns.Add("Value", typeof(int));
// fill with some random data
Random rand = new Random();
int sum = 0;
for (int i = 0; i < 20; i++) {
int val = rand.Next(50);
dt.Rows.Add(false, "Row " + i.ToString(), val);
sum += val;
}
// add footer row
dt.Rows.Add(true, "Total", sum);

// display
using(Form form = new Form())
using (DataGridView grid = new DataGridView()) {
grid.Dock = DockStyle.Fill;
grid.AllowUserToAddRows = false;
form.Controls.Add(grid);
grid.DataSource = new CustomDataView(dt.DefaultView,
"IsFooter", ListSortDirection.Ascending);
grid.Columns[0].Visible = false;
Application.Run(form);
}
}
 
public class CustomDataView : IBindingListView, IBindingList, IList,
ICollection, IEnumerable, ITypedList, ISupportInitializeNotification,
ISupportInitialize {
readonly DataView parent;
readonly ListSortDescription fixedSort;
public CustomDataView(DataView parent, string sortProperty,
ListSortDirection sortDirection) {
if (parent == null) throw new ArgumentNullException();
this.parent = parent;
if (!SupportsSorting || !SupportsAdvancedSorting) {
throw new InvalidOperationException("Advanced sorting
is required");
}
fixedSort = new
ListSortDescription(GetItemProperties(null)[sortProperty],
sortDirection);
RemoveSort();
}

#region IBindingListView Members

void IBindingListView.ApplySort(ListSortDescriptionCollection
sorts) {
ListSortDescription[] sortArray = new
ListSortDescription[sorts.Count + 1];
sorts.CopyTo(sortArray, 1);
sortArray[0] = fixedSort;
ApplySort(sortArray);
}

string IBindingListView.Filter {
get {
return ((IBindingListView)parent).Filter;
}
set {
((IBindingListView)parent).Filter = value;
}
}

void IBindingListView.RemoveFilter() {
((IBindingListView)parent).RemoveFilter();
}

ListSortDescriptionCollection
IBindingListView.SortDescriptions {
get {
ListSortDescriptionCollection sorts =
((IBindingListView)parent).SortDescriptions;
if(sorts == null || sorts.Count == 0) return sorts;
ListSortDescription[] sortArray = new
ListSortDescription[sorts.Count - 1];
for (int i = 1; i < sorts.Count; i++) {
sortArray[i - 1] = sorts;
}
return new ListSortDescriptionCollection(sortArray);
}
}

public bool SupportsAdvancedSorting {
get { return
((IBindingListView)parent).SupportsAdvancedSorting; }
}

bool IBindingListView.SupportsFiltering {
get { return
((IBindingListView)parent).SupportsFiltering; }
}

#endregion

#region IBindingList Members

void IBindingList.AddIndex(PropertyDescriptor property) {
((IBindingList)parent).AddIndex(property);
}

object IBindingList.AddNew() {
return ((IBindingList)parent).AddNew();
}

bool IBindingList.AllowEdit {
get { return ((IBindingList)parent).AllowEdit; }
}

bool IBindingList.AllowNew {
get { return ((IBindingList)parent).AllowNew; }
}

bool IBindingList.AllowRemove {
get { return ((IBindingList)parent).AllowRemove; }
}

void IBindingList.ApplySort(PropertyDescriptor property,
ListSortDirection direction) {
ApplySort(fixedSort, new ListSortDescription(property,
direction));
}
void ApplySort(params ListSortDescription[] sorts) {
((IBindingListView)parent).ApplySort(new
ListSortDescriptionCollection(sorts));
}

int IBindingList.Find(PropertyDescriptor property, object key)
{
return ((IBindingList)parent).Find(property, key);
}

public bool IsSorted {
get { return ((IBindingList)parent).IsSorted &&
((IBindingListView)parent).SortDescriptions.Count > 1; }
}

event ListChangedEventHandler IBindingList.ListChanged {
add { ((IBindingList)parent).ListChanged += value; }
remove { ((IBindingList)parent).ListChanged -= value; }
}

void IBindingList.RemoveIndex(PropertyDescriptor property) {
((IBindingList)parent).RemoveIndex(property);
}

public void RemoveSort() {
ApplySort(fixedSort);
}

ListSortDirection IBindingList.SortDirection {
get {
if (IsSorted) {
return
((IBindingListView)parent).SortDescriptions[1].SortDirection;
} else {
return ListSortDirection.Ascending;
}
}
}

PropertyDescriptor IBindingList.SortProperty {
get {
if (IsSorted) {
return
((IBindingListView)parent).SortDescriptions[1].PropertyDescriptor;
} else {
return null;
}
}
}

bool IBindingList.SupportsChangeNotification {
get { return
((IBindingList)parent).SupportsChangeNotification; }
}

bool IBindingList.SupportsSearching {
get { return ((IBindingList)parent).SupportsSearching; }
}

public bool SupportsSorting {
get { return ((IBindingList)parent).SupportsSorting; }
}

#endregion

#region IList Members

int System.Collections.IList.Add(object value) {
return ((IList)parent).Add(value);
}

void System.Collections.IList.Clear() {
((IList)parent).Clear();
}

bool System.Collections.IList.Contains(object value) {
return ((IList)parent).Contains(value);
}

int System.Collections.IList.IndexOf(object value) {
return ((IList)parent).IndexOf(value);
}

void System.Collections.IList.Insert(int index, object value)
{
((IList)parent).Insert(index, value);
}

bool System.Collections.IList.IsFixedSize {
get { return ((IList)parent).IsFixedSize; }
}

bool System.Collections.IList.IsReadOnly {
get { return ((IList)parent).IsReadOnly; }
}

void System.Collections.IList.Remove(object value) {
((IList)parent).Remove(value);
}

void System.Collections.IList.RemoveAt(int index) {
((IList)parent).RemoveAt(index);
}

object System.Collections.IList.this[int index] {
get {
return ((IList)parent)[index];
}
set {
((IList)parent)[index] = value;
}
}

#endregion

#region ICollection Members

void System.Collections.ICollection.CopyTo(Array array, int
index) {
((ICollection)parent).CopyTo(array, index);
}

int System.Collections.ICollection.Count {
get { return ((ICollection)parent).Count; }
}

bool System.Collections.ICollection.IsSynchronized {
get { return ((ICollection)parent).IsSynchronized; }
}

object System.Collections.ICollection.SyncRoot {
get { return ((ICollection)parent).SyncRoot; }
}

#endregion

#region IEnumerable Members

System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator() {
return ((IEnumerable)parent).GetEnumerator();
}

#endregion

#region ITypedList Members

PropertyDescriptorCollection
ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) {
return GetItemProperties(listAccessors);
}
private PropertyDescriptorCollection
GetItemProperties(PropertyDescriptor[] listAccessors) {
return
((ITypedList)parent).GetItemProperties(listAccessors);
}

string ITypedList.GetListName(PropertyDescriptor[]
listAccessors) {
return ((ITypedList)parent).GetListName(listAccessors);
}

#endregion

#region ISupportInitializeNotification Members

event EventHandler ISupportInitializeNotification.Initialized
{
add { ((ISupportInitializeNotification)parent).Initialized
+= value; }
remove {
((ISupportInitializeNotification)parent).Initialized -= value; }
}

bool ISupportInitializeNotification.IsInitialized {
get { return
((ISupportInitializeNotification)parent).IsInitialized; }
}

#endregion

#region ISupportInitialize Members

void ISupportInitialize.BeginInit() {
((ISupportInitialize)parent).BeginInit();
}

void ISupportInitialize.EndInit() {
((ISupportInitialize)parent).EndInit();
}

#endregion
}
 
Thank you very much! It worked in a sample, so I will adapt it into my project.
Vanessa

Marc Gravell said:
public class CustomDataView : IBindingListView, IBindingList, IList,
ICollection, IEnumerable, ITypedList, ISupportInitializeNotification,
ISupportInitialize {
readonly DataView parent;
readonly ListSortDescription fixedSort;
public CustomDataView(DataView parent, string sortProperty,
ListSortDirection sortDirection) {
if (parent == null) throw new ArgumentNullException();
this.parent = parent;
if (!SupportsSorting || !SupportsAdvancedSorting) {
throw new InvalidOperationException("Advanced sorting
is required");
}
fixedSort = new
ListSortDescription(GetItemProperties(null)[sortProperty],
sortDirection);
RemoveSort();
}

#region IBindingListView Members

void IBindingListView.ApplySort(ListSortDescriptionCollection
sorts) {
ListSortDescription[] sortArray = new
ListSortDescription[sorts.Count + 1];
sorts.CopyTo(sortArray, 1);
sortArray[0] = fixedSort;
ApplySort(sortArray);
}

string IBindingListView.Filter {
get {
return ((IBindingListView)parent).Filter;
}
set {
((IBindingListView)parent).Filter = value;
}
}

void IBindingListView.RemoveFilter() {
((IBindingListView)parent).RemoveFilter();
}

ListSortDescriptionCollection
IBindingListView.SortDescriptions {
get {
ListSortDescriptionCollection sorts =
((IBindingListView)parent).SortDescriptions;
if(sorts == null || sorts.Count == 0) return sorts;
ListSortDescription[] sortArray = new
ListSortDescription[sorts.Count - 1];
for (int i = 1; i < sorts.Count; i++) {
sortArray[i - 1] = sorts;
}
return new ListSortDescriptionCollection(sortArray);
}
}

public bool SupportsAdvancedSorting {
get { return
((IBindingListView)parent).SupportsAdvancedSorting; }
}

bool IBindingListView.SupportsFiltering {
get { return
((IBindingListView)parent).SupportsFiltering; }
}

#endregion

#region IBindingList Members

void IBindingList.AddIndex(PropertyDescriptor property) {
((IBindingList)parent).AddIndex(property);
}

object IBindingList.AddNew() {
return ((IBindingList)parent).AddNew();
}

bool IBindingList.AllowEdit {
get { return ((IBindingList)parent).AllowEdit; }
}

bool IBindingList.AllowNew {
get { return ((IBindingList)parent).AllowNew; }
}

bool IBindingList.AllowRemove {
get { return ((IBindingList)parent).AllowRemove; }
}

void IBindingList.ApplySort(PropertyDescriptor property,
ListSortDirection direction) {
ApplySort(fixedSort, new ListSortDescription(property,
direction));
}
void ApplySort(params ListSortDescription[] sorts) {
((IBindingListView)parent).ApplySort(new
ListSortDescriptionCollection(sorts));
}

int IBindingList.Find(PropertyDescriptor property, object key)
{
return ((IBindingList)parent).Find(property, key);
}

public bool IsSorted {
get { return ((IBindingList)parent).IsSorted &&
((IBindingListView)parent).SortDescriptions.Count > 1; }
}

event ListChangedEventHandler IBindingList.ListChanged {
add { ((IBindingList)parent).ListChanged += value; }
remove { ((IBindingList)parent).ListChanged -= value; }
}

void IBindingList.RemoveIndex(PropertyDescriptor property) {
((IBindingList)parent).RemoveIndex(property);
}

public void RemoveSort() {
ApplySort(fixedSort);
}

ListSortDirection IBindingList.SortDirection {
get {
if (IsSorted) {
return
((IBindingListView)parent).SortDescriptions[1].SortDirection;
} else {
return ListSortDirection.Ascending;
}
}
}

PropertyDescriptor IBindingList.SortProperty {
get {
if (IsSorted) {
return
((IBindingListView)parent).SortDescriptions[1].PropertyDescriptor;
} else {
return null;
}
}
}

bool IBindingList.SupportsChangeNotification {
get { return
((IBindingList)parent).SupportsChangeNotification; }
}

bool IBindingList.SupportsSearching {
get { return ((IBindingList)parent).SupportsSearching; }
}

public bool SupportsSorting {
get { return ((IBindingList)parent).SupportsSorting; }
}

#endregion

#region IList Members

int System.Collections.IList.Add(object value) {
return ((IList)parent).Add(value);
}

void System.Collections.IList.Clear() {
((IList)parent).Clear();
}

bool System.Collections.IList.Contains(object value) {
return ((IList)parent).Contains(value);
}

int System.Collections.IList.IndexOf(object value) {
return ((IList)parent).IndexOf(value);
}

void System.Collections.IList.Insert(int index, object value)
{
((IList)parent).Insert(index, value);
}

bool System.Collections.IList.IsFixedSize {
get { return ((IList)parent).IsFixedSize; }
}

bool System.Collections.IList.IsReadOnly {
get { return ((IList)parent).IsReadOnly; }
}

void System.Collections.IList.Remove(object value) {
((IList)parent).Remove(value);
}

void System.Collections.IList.RemoveAt(int index) {
((IList)parent).RemoveAt(index);
}

object System.Collections.IList.this[int index] {
get {
return ((IList)parent)[index];
}
set {
((IList)parent)[index] = value;
}
}

#endregion

#region ICollection Members

void System.Collections.ICollection.CopyTo(Array array, int
index) {
((ICollection)parent).CopyTo(array, index);
}

int System.Collections.ICollection.Count {
get { return ((ICollection)parent).Count; }
}

bool System.Collections.ICollection.IsSynchronized {
get { return ((ICollection)parent).IsSynchronized; }
}

object System.Collections.ICollection.SyncRoot {
get { return ((ICollection)parent).SyncRoot; }
}

#endregion

#region IEnumerable Members

System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator() {
return ((IEnumerable)parent).GetEnumerator();
}

#endregion

#region ITypedList Members

PropertyDescriptorCollection
ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) {
return GetItemProperties(listAccessors);
}
private PropertyDescriptorCollection
GetItemProperties(PropertyDescriptor[] listAccessors) {
return
((ITypedList)parent).GetItemProperties(listAccessors);
}

string ITypedList.GetListName(PropertyDescriptor[]
listAccessors) {
return ((ITypedList)parent).GetListName(listAccessors);
}

#endregion

#region ISupportInitializeNotification Members

event EventHandler ISupportInitializeNotification.Initialized
{
add { ((ISupportInitializeNotification)parent).Initialized
+= value; }
remove {
((ISupportInitializeNotification)parent).Initialized -= value; }
}

bool ISupportInitializeNotification.IsInitialized {
get { return
((ISupportInitializeNotification)parent).IsInitialized; }
}

#endregion

#region ISupportInitialize Members

void ISupportInitialize.BeginInit() {
((ISupportInitialize)parent).BeginInit();
}

void ISupportInitialize.EndInit() {
((ISupportInitialize)parent).EndInit();
}

#endregion
}
 
Hi Marc Gravell,

Even i have similar problem what you have explained earlier for the above thread.

I just want to clarify my doubt regarding IBindingListView.

In my application i have used BindingSource that i have binded to a DataGridView that, BindingSource i have associated to a class with four properties.

I'm able to display those property contents in the DataGridView but unable to filter it. I have 50 records in the BindingSource in that i need to filter only those records starting from the Itemid greater than 10 and lesser than or equal to 30. I have tried the below methods....

1) itemsBindingSource.Filter = "Itemid > =" + 10 + " and Itemid <=" + 30;

2) temsBindingSource.Filter="Slno between " + startno + " and " + Endno; (This is what you have suggested in the last discussion)

I tried itemsBindingSource.SupportsFiltering property eventhough it always returns false.

Actually i'm implementing the above code for DataGridView paging, so that i can display few records using filter in a single page.


Thanks in advance,

Gajendra
 
I don't think it would be simple to apply paging using a filter; in
particular, the code for adding/removing items (at the bottom of the
DataGridView) would be a real pain. As it happens I do have a
(predicate-oriented) filtered-list implementation up my sleeve, but I
don't think it is a good fit for what you are doing...

Being pragmatic, for paging, would it not be easier to simply copy the
page that you want from your original list into the data-bound list?
(This is what you have suggested in the last discussion)
Did I? I don't remember that, and can't see it in the archive...

For info, this discussion was really about sorting, not filtering;
they are very different beasts...

If you are paging over a very large result, consider also "virtual
mode".

Marc
 
Hi Marc,

Thanx for your reply...

Basically I have an example of datagridview paging using dataset where he
used to show the records in pages through filter condition. The following
line is used for filter condition in that example.

bindingSource1.Filter = "RecordID >= " + RecordID1 + " and RecordID <= " +
RecordID2;
GridView1.DataSource = bindingSource1;

For your kind reference follow the link which has the above code..
http://www.codeproject.com/KB/miscctrl/Pagable_DatagridView.aspx

The project which includes the above two statements is working fine & the
supportsFiltering is also returning true. So now I want to implement the same
through BindingSource using collections. Hence I have binded to a class which
has four properties. The binding part & displaying in gridview is working
fine.Now what I want exactly is, I want to display only 100 records in first
page among 500 records. So i need to filter for a certain range so that it
fulfils my requirement.

Hope you understood my requirement. I am struggling for this part from past
few days, so if u please help me in this regard as soon as possible, it will
be very much appreciable.

Thanks once again...
 
I understand whay you are trying to do... but using a filter is
probably not going to be your best option here. The point is that
BindingList<T> etc don't support filter "out of the box". I have a
filtering example, but it is 556 LOC (mainly due to the complexities
of dealing with full property notification over bound data. And this
is the *simple* version that uses a predicate filter (not a parser).

Quite simply - I think that a filtered list would be the wrong answer
to your problem; all you need is paging...

You don't indicate whay .NET version you are using - if you have 3.5
this would be even easier (Skip() and Take()), but since paging is so
simple how about simply something like (note most of this code is the
example; the list itself is very simple):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

class DemoData
{
private int value1;
private double value2;
[DisplayName("Value 1")]
public int Value1 { get { return value1; } set { value1 =
value; } }
[DisplayName("Value 2")]
public double Value2 { get { return value2; } set { value2 =
value; } }
}
static class Program
{

[STAThread]
static void Main()
{
List<DemoData> data = new List<DemoData>();
Random rand = new Random();
for (int i = 0; i < 10000; i++)
{
DemoData dd = new DemoData();
dd.Value1 = rand.Next(500);
dd.Value2 = rand.NextDouble() * 500;
data.Add(dd);
}

Application.EnableVisualStyles();
using(Form form = new Form())
using (DataGridView view = new DataGridView())
using (Button next = new Button())
using (Button prev = new Button())
{
PagedList<DemoData> paged = new
PagedList<DemoData>(data, 0, 50);
next.Click += delegate { paged.PageIndex += 1; };
prev.Click += delegate { paged.PageIndex -= 1; };
view.Dock = DockStyle.Fill;
view.DataSource = paged;
next.Dock = prev.Dock = DockStyle.Bottom;
next.Text = ">";
prev.Text = "<";
form.Controls.AddRange(new Control[] { view, next,
prev });
Application.Run(form);
}
}
}
class PagedList<T> : BindingList<T>
{
private readonly IList<T> source;
public PagedList(IList<T> source)
{
if (source == null) throw new
ArgumentNullException("source");
this.source = source;
SetPage(0, source.Count);
}
public PagedList(IList<T> source, int pageIndex, int pageSize)
{
if (source == null) throw new
ArgumentNullException("source");
this.source = source;
SetPage(pageIndex, pageSize);
}
private int pageIndex, pageSize;
public int PageIndex { get { return pageIndex; } set
{ SetPage(value, PageSize); } }
public int PageSize { get { return pageSize; } set
{ SetPage(PageIndex, value); } }
public void SetPage(int pageIndex, int pageSize)
{
if (pageIndex < 0) throw new
ArgumentOutOfRangeException("pageIndex");
if (pageSize <= 0) throw new
ArgumentOutOfRangeException("pageSize");
this.pageIndex = pageIndex;
this.pageSize = pageSize;

bool wasRaising = RaiseListChangedEvents;
RaiseListChangedEvents = false;
try
{
Clear();
int start = pageSize * pageIndex, end = start +
pageSize;
if (end > source.Count) end = source.Count;
for (int i = start; i < end; i++)
{
Add(source);
}
}
finally
{
RaiseListChangedEvents = wasRaising;
ResetBindings();
}

}
}
 
Back
Top