From: gajendra.baragur on
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


From: Marc Gravell on
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
From: Gajendra on
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...


Marc Gravell wrote:
>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

From: Marc Gravell on
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[i]);
}
}
finally
{
RaiseListChangedEvents = wasRaising;
ResetBindings();
}

}
}