Datasource and FilterToUse

Posts   
 
    
Darren166
User
Posts: 41
Joined: 30-Jan-2007
# Posted on: 02-Feb-2007 20:27:33   

Latest Build, net 2.0, self servicing

Hi, I have no idea why this is causing me a problem but I have a very simple setup of a textbox with search button and a gridview. I use a llblgendatasource control to retrieve a typed list. I want to type a value in the textbox and see the gridview filtered by that value. I am using the following code;

protected void Page_Load(object sender, EventArgs e)
{

    string SearchTerm = "TEST";
    if (txtSearchTerm.Text != "")
    {
        SearchTerm = txtSearchTerm.Text;
    }

    IPredicateExpression SearchFilter = new PredicateExpression();
    SearchFilter.Add(GroupFields.Code % SearchTerm);
    LLBLSearchProducts.FilterToUse = SearchFilter;

}

The gridview is initially filtered on the word 'TEST' as expected, but subsequent callbacks via the search button do not refresh the grid. Using SQL Profiler I can see that no further SQL calls are made. Using the debugger it appears that everything is being assigned as expected, with the new search term picked up, the filter created and the datasource filtertouse property reassigned. My understanding is that filtertouse should trigger the datasource to refresh the data each time. Am I missing something here??

Darren

Darren166
User
Posts: 41
Joined: 30-Jan-2007
# Posted on: 02-Feb-2007 20:30:15   

Sorry, I forgot to mention that I am not using the select parameters as I will be expanding the filter condition with Multiple OR statements. I haven't done that yet as I cannot get the basics to work.

Darren

(p.s. HELP!)

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 02-Feb-2007 22:19:15   

Did you try setting the filter in the button handler? You now set the filter in the page load. The textbox value on the POSTBACK is filled in after the page load.

Frans Bouma | Lead developer LLBLGen Pro
Darren166
User
Posts: 41
Joined: 30-Jan-2007
# Posted on: 03-Feb-2007 19:56:50   

Thanks Otis, putting it into the button handling event fixed it. I need to gen up on event order obviously, though I am confused because when I added a label to the page to display the textbox value, it worked fine. i.e. the following code in page_load shows the textbox value but does not process the filter

protected void Page_Load(object sender, EventArgs e)
{
    string SearchTerm = "TEST";
    if (txtSearchTerm.Text != "")
    {
        SearchTerm = txtSearchTerm.Text;
    }

    Label1.Text = SearchTerm;

    IPredicateExpression SearchFilter = new PredicateExpression();
    SearchFilter.Add(GroupFields.Code % SearchTerm);
    LLBLSearchProducts.FilterToUse = SearchFilter;
 }

Also, stepping through debugger shows the filter has picked up the search term, but it doesn't filter the typed list unless I handle it all in the button event. This seems a .net issue, but can anyone explain it to me?

Darren

Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 03-Feb-2007 23:43:36   

I'd suggest reviewing the Page Life Cycle:

http://msdn2.microsoft.com/en-us/library/ms178472(VS.80).aspx

Darren166
User
Posts: 41
Joined: 30-Jan-2007
# Posted on: 04-Feb-2007 03:57:42   

Thanks Chester, but on that page it says the following about the pre_load event (which happens before the page_load)

'After the Page raises this event, it loads view state for itself and all controls, and then processes any postback data included with the Request instance.'

and the textbox data is definitely available during page_load, it is easy to test with a simple text box and label with the label value assigned from the textbox during page_load. All very basic .net stuff.

It is not the availability of the textbox value that I am having difficulty with it is the fact that when you set filtertouse from it during the page_load event the datasource does not refetch the data.

Can someone please test this and see for themselves....

Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 04-Feb-2007 21:24:49   

Darren166 wrote:

Thanks Chester, but on that page it says the following about the pre_load event (which happens before the page_load)

'After the Page raises this event, it loads view state for itself and all controls, and then processes any postback data included with the Request instance.'

and the textbox data is definitely available during page_load, it is easy to test with a simple text box and label with the label value assigned from the textbox during page_load. All very basic .net stuff.

It is not the availability of the textbox value that I am having difficulty with it is the fact that when you set filtertouse from it during the page_load event the datasource does not refetch the data.

Can someone please test this and see for themselves....

I don't know the inner-workings of the datasource control very well, but the fact that your filter works in the button_click event and not in page load leads me to believe that the datasource control isn't fully "loaded" until AFTER the load event. I'm guessing that if you put your code in the Page's PreRender event (or, new to 2.0, the LoadComplete event) it will work. Can you try that?

Unfortunately there is a common misperception out there that the page's Load event is the "proper" event to use. But it simply isn't true. It's just a convenient event to use for most scenarios and one that you are encouraged to use if VS.NET is your editor of choice. But it's not always the correct event to use, especially in databinding scenarios where all controls' Load events must already have completed.

Darren166
User
Posts: 41
Joined: 30-Jan-2007
# Posted on: 05-Feb-2007 16:12:10   

Thanks again Chester, I have put the code into the LoadComplete event and it does work there. I couldn't put it into button_click as I needed to filter on a session value as a default when the page loaded.

I guess I could leave it at that as I have a working page, but it still irks me that filtertouse works in the page_load event when it is set directly by, for example,

LLBLSearchProducts.FilterToUse = "Holland";

but not when referencing an available textbox property such as

LLBLSearchProducts.FilterToUse = txtSearch.Text;

Darren

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 06-Feb-2007 08:36:18   

And what code do you have in the button click event?

I would have set the LLBLGenProDataSource filter in the button click, and then I would have set LLBLGenProDataSource.Refetch = true, and maybe a re-bind would help also.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 06-Feb-2007 11:00:57   

Darren166 wrote:

Thanks again Chester, I have put the code into the LoadComplete event and it does work there. I couldn't put it into button_click as I needed to filter on a session value as a default when the page loaded.

I guess I could leave it at that as I have a working page, but it still irks me that filtertouse works in the page_load event when it is set directly by, for example,

LLBLSearchProducts.FilterToUse = "Holland";

but not when referencing an available textbox property such as

LLBLSearchProducts.FilterToUse = txtSearch.Text; Darren

Like I said, this is likely because the textbox's value isn't set to the value you filled in when the postback happens. When you hardcode the value, then of course it's used, but when you fill in a value in the form, and the postback happens, the value is filled in at a later stage by asp.net in the page lifecycle. I have no idea which one, please consult MS documentation for that. All I do know is that when the event handler of a button is called, the form objects do have their values so you can access them to act accordingly,.

Frans Bouma | Lead developer LLBLGen Pro
Darren166
User
Posts: 41
Joined: 30-Jan-2007
# Posted on: 06-Feb-2007 14:56:13   

Ok, after a lot of research into this issue, I finally understand what is happening. I am posting the scenario here so that others who come across it may understand. Thanks to everyone who helped me.

If you have a datasource and a gridview that references the datasource on your page, the grid is automatically databound to the datasource. It decides whether or not it needs to be databound by a flag - 'RequiresDataBinding'. The flag is set depending on several factors; whether there is a viewstate for the gridview and whether the datasource has changed in some way. If a viewstate exists and the datasource is unchanged then the gridview is not databound. If the view state does not exist or the datasource has changed then the gridview is databound.

The gridview is loaded straight after page_load and rendered (where the databinding occurs) straight after the page PreRender event. For the 'RequiresDataBinding' flag to be set to true, the datasource must be changed (eg filter added) between these events.

Basically, if you set the filtertouse property in page_load then you must either turn off the viewstate for the gridview or manually bind the grid. If neither of these are appropriate then (and this is the better course of action) set the filtertouse property in the pages LoadComplete event.

I hope this helps people out in future so that they do not spend hours chasing the wrong thing down like I did!!

Darren