Help! - How to apply Filter on FilteredBindingList?

Help! - How to apply Filter on FilteredBindingList?

Old forum URL: forums.lhotka.net/forums/t/6165.aspx


andrewrajcoomar posted on Thursday, January 15, 2009

I am trying to add a filter functionality to my baseform using a combobox and textbox controls. I am using the BindingSource property in my baseform to add my column names to the combobox, using reflection. The idea is,  the user can select any column and type a value in the textbox, hit the Filter button, and then I apply the filter. If there are no matches, I inform the user and discard the criterion.

I do not know how to apply the filter to the underlying list. As you'll see, I believe I am trying to apply the filter to the wrong object (what I need is a way to declare a property of type myBOList, in my baseform and be able to set it's value from another class, don't know...)

This is my code from my inherited form :

Public Sub New()

......

Dim sortedList As New SortedBindingList(Of ChartFieldInfo)(_ChartFieldList)

Dim filteredList As New FilteredBindingList(Of ChartFieldInfo)(sortedList)

'set my grid bindingsource datasource

Me.ChartFieldListBindingSource.DataSource = filteredList

'set my baseform BindingSource property

MyBase.BindingSource = Me.ChartFieldListBindingSource

 

....

and in my baseform

Private WithEvents _BindingSource As BindingSource

Protected Property BindingSource() As BindingSource

Get

Return _BindingSource

End Get

Set(ByVal value As BindingSource)

_BindingSource = value

baseBindingNavigator.BindingSource = value

If _BindingSource IsNot Nothing Then

' subscribe to events

AddHandler _BindingSource.BindingComplete, AddressOf BindingComplete

AddHandler _BindingSource.DataSourceChanged, AddressOf BindingSourceChanged

' get a reference to the data source

BindingSourceChanged(New Object, New EventArgs)

End If

End Set

End Property

.....

Private Sub BindingSourceChanged(ByVal sender As Object, ByVal e As EventArgs)

If _BindingSource IsNot Nothing Then

BuildColumnNameLookup()

End If

End Sub

 

....

Private Sub BuildColumnNameLookup()

If BindingSource.List.Count > 0 Then

BindingNavigatorLookup.Items.Add("(None)")

For Each p As PropertyInfo In _BindingSource.Item(0).GetType().GetProperties

BindingNavigatorLookup.Items.Add(p.Name)

Next

End If

End Sub

In my baseform, I have a button named btnApplyFilter. On the click event, I expect I can apply the filter. I have tried this:

...

_BindingSource.Filter = BindingNavigatorLookup.SelectedText = BindingNavigatorFilterValue.Text

It seems like _BindingSource is not the right object to use. What should it be (see my last question below).

I am not sure what else to do at this point, short of selecting from SQL again. But I believe I can apply the filter to my existing list. Please explain how I can implement this.

Also, how do I create a property, and of what type, in my baseform, so that I can set it from my inherited form, to the value of my filteredList, and be able to reference it in my baseform?

Thanks,

Andrew

RockfordLhotka replied on Thursday, January 15, 2009

FilteredBindingList is fully covered in the CSLA .NET Version 2.1 Handbook ebook.

In short, you provide a delegate (or now a lambda) that is defined by the FilterProvider delegate signature. You can look in the CSLA project at the DefaultFilter class to see how such a method is constructed.

Then you just pass that method to the ApplyFilter() method, or set it as the default filter for the collection.

tarekahf replied on Sunday, February 08, 2009

Rocky,

Thank you for the info.

I am looking for some sample code to Filter collection of base type "BusinessListBase".

I think I know how to do that, however, I am a bit lost on how to bind the list to the DataGrid.

I have developed the BusinessListBase collection object, and it is working properly, and I can see the result after binding it to the DataGrid View.

My question is that after I apply the filter (using FilterProvider), I get a new filtered list successfully, but the type of the new filtered collection (FilteredBindingList) is different that the original collection (from BusinessListBase) which is already bound to the GridView, so I am not sure how to handle this situation. Because I try to covert (using CTYPE) from the FilteredBindingList type to the BusinessListBase type, and it is giving me compile time error.

Please help.

Tarek.

RockfordLhotka replied on Sunday, February 08, 2009

Your UI code needs to change the bindingSource.DataSource to point to the filteredbindinglist.

 

Data binding doesn’t care about the type of the target object – only that the target object have the properties needed by the UI controls. Even though your collection type is different, the filtered collection points to the same child objects, and so they have the same properties, and so data binding will be happy.

 

Rocky

 

 

From: tarekahf [mailto:cslanet@lhotka.net]
Sent: Sunday, February 08, 2009 8:11 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Help! - How to apply Filter on FilteredBindingList?

 

Rocky,

Thank you for the info.

I am looking for some sample code to Filter collection of base type "BusinessListBase".

I think I know how to do that, however, I am a bit lost on how to bind the list to the DataGrid.

I have developed the BusinessListBase collection object, and it is working properly, and I can see the result after binding it to the DataGrid View.

My question is that after I apply the filter (using FilterProvider), I get a new filtered list successfully, but the type of the new filtered collection (FilteredBindingList) is different that the original collection (from BusinessListBase) which is already bound to the GridView, so I am not sure how to handle this situation. Because I try to covert (using CTYPE) from the FilteredBindingList type to the BusinessListBase type, and it is giving me compile time error.

Please help.

Tarek.



tarekahf replied on Sunday, February 08, 2009

Ok... this is now making sense !

I thought I need to apply the filter on the UI code during the Select Event of the CSLA DataSource, right ?

I mean something like this:

e.BusinessObject = TheNewFilteredList

Or do you mean that I should deal with the GridView Properties directly in the UI code to change the DataSource ?

Tarke.

RockfordLhotka replied on Sunday, February 08, 2009

Sorry, didn’t realize you were talking web.

 

You can do filtering and sorting at several levels in a web app, including the code behind the page, the object factory method, the DataPortal_XYZ method or the stored procedure/SQL statement. I discuss this in the CSLA .NET Version 2.1 Handbook ebook, and in some previous threads on this forum (though the topic is usually sorting, not filtering).

 

It is most efficient to filter in the database, then the DataPortal_XYZ method. The other two options are least efficient, because you’ve pulled out all that data that you then discard.

 

But you are right – you do the filter in the Select event handler if you are going to do the filter in the UI.

 

Rocky

 

 

From: tarekahf [mailto:cslanet@lhotka.net]
Sent: Sunday, February 08, 2009 3:22 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Help! - How to apply Filter on FilteredBindingList?

 

Ok... this is now making sense !

I thought I need to apply the filter on the UI code during the Select Event of the CSLA DataSource, right ?

I mean something like this:

e.BusinessObject = TheNewFilteredList

Or do you mean that I should deal with the GridView Properties directly in the UI code to change the DataSource ?

Tarke.



tarekahf replied on Sunday, February 08, 2009

Thanks a lot ...!

It is working 100% successfully now.

As a matter of fact, I liked the other least efficient methods, because they are very fast ...

This is because, I am pulling data from 3 different Databases (Adabas/Unix, MS Access, SQL Server) and building a CSLA list of max 300 items. It takes a while to build the list from the Database, and once the master list is cashed on a session variable, then filtering will be very quick, and I like it !

(Note: I used the FilterProvider to implement a complex filter criteria).

One more question:

After I apply the filter, and in order to display the new items in the GridView, I am using the following commands:

myGridView.DataBind()
myGridView.PageIndex = 0

Is this the right method ?

Regards ...

Tarek.

RockfordLhotka replied on Sunday, February 08, 2009

Yes, that is the right way to trigger a rebind of the grid’s data.

 

Rocky

tarekahf replied on Sunday, February 08, 2009

(Note: I almost forgot about the CSLA 2.1 Handbook we purchased last year... it is great.)

Things can't be better for today !

Now, I want to apply sorting so that when you click on the GridView Column Header, it will sort accordingly. Also, at the same time, I want to maintain the filter. Is this possible ?

Just give me hints, I will do the rest.

Tarek.

RockfordLhotka replied on Monday, February 09, 2009

You can use both FilteredBindingList and SortedBindingList together.

 

I typically filter first, then sort, so the sort has less work to do:

 

filtered = new FilteredBindingList(_originalList);

sorted = new SortedBindingList(filtered);

 

Remember these are each views over the other, so if you do filtered.ApplyFilter() and then sorted.ApplySort() you’ll end up with a filtered, sorted list.

 

Rocky

 

 

From: tarekahf [mailto:cslanet@lhotka.net]
Sent: Sunday, February 08, 2009 11:57 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: RE: Help! - How to apply Filter on FilteredBindingList?

 

(Note: I almost forgot about the CSLA 2.1 Handbook we purchased last year... it is great.)

Things can't be better for today !

Now, I want to apply sorting so that when you click on the GridView Column Header, it will sort accordingly. Also, at the same time, I want to maintain the filter. Is this possible ?

Just give me hints, I will do the rest.

Tarek.



tarekahf replied on Monday, February 09, 2009

When I insert object into CSLA List, and do save as per the following code:

    Protected Sub srcObject_InsertObject(ByVal sender As Object, ByVal e As Csla.Web.InsertObjectArgs) Handles srcObject.InsertObject
        Try
            Dim obj As MyCSLA_List = GetMyList()
            Dim item As MyCSLA_Object = obj.AddNew
            Csla.Data.DataMapper.Map(e.Values, item)
            item.DoCalcProperties()  ' Do Calculations here
            Session("currentObject") = obj.Save
            e.RowsAffected = 1

        Catch ex As Csla.DataPortalException
            Me.ErrorLabel.Text = ex.BusinessException.Message
            e.RowsAffected = 0

        Catch ex As Exception
            Me.ErrorLabel.Text = ex.Message
            e.RowsAffected = 0
        End Try
    End Sub

Things are OK, but I have the following question:

What is the purpose of e.RowsAffected = 1 ?

Tarek.

RockfordLhotka replied on Monday, February 09, 2009

The web forms data binding infrastructure wants to know how many rows are affected by the operation, and the CslaDataSource allows (requires that) you to provide that information.

 

Rocky

 

From: tarekahf [mailto:cslanet@lhotka.net]
Sent: Monday, February 09, 2009 4:59 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: RE: Help! - How to apply Filter on FilteredBindingList?

 

When I insert object into CSLA List, and do save as per the following code:

    Protected Sub srcObject_InsertObject(ByVal sender As Object, ByVal e As Csla.Web.InsertObjectArgs) Handles srcObject.InsertObject
        Try
            Dim obj As MyCSLA_List = GetMyList()
            Dim item As MyCSLA_Object = obj.AddNew
            Csla.Data.DataMapper.Map(e.Values, item)
            item.DoCalcProperties()  ' Do Calculations here
            Session("currentObject") = obj.Save
            e.RowsAffected = 1
 
        Catch ex As Csla.DataPortalException
            Me.ErrorLabel.Text = ex.BusinessException.Message
            e.RowsAffected = 0
 
        Catch ex As Exception
            Me.ErrorLabel.Text = ex.Message
            e.RowsAffected = 0
        End Try
    End Sub

Things are OK, but I have the following questions:

What is the purpose of e.RowsAffected = 1 ?

Tarek.



Copyright (c) Marimer LLC