WebForms Databinding : Need clarification on intercepting events

Posts   
 
    
Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 21-Sep-2006 21:48:21   

In some scenarios the web data source control fires the PerformSelect unexpected. In other scenarios, it doest fire it when I am expecting it to.

In the current scenario, I have a web data source control with a select parameter pointed at a hidden field. the value of the hidden field is updated by another web user control. So the customer list web user control raises an event, the containing for handles the event, and delegates the event arguments to the customer demographics web user control.

The customer demographics web user control has the data source control in it that is bound to the hidden field in the customer demographics web user control. In the customer demographics web user control the PerformSelect event only gets fired once, and that is when the control is first loaded. I would suspect it to fire each time the value property of the hidden field gets set.

Does this scenario make sense?

My question is this, can you provide some information other than the section titled "Intercepting activity", because this scetion just gives us a high level of what should happen.

Here is my code behind for this scenario:


    public void ShowDemographics(int customerId)
    {
        hfCustomerId.Value = customerId.ToString();
        //LoadData(customerId);
    }
    protected void CustomerDemoDataSource_PerformSelect(object sender, PerformSelectEventArgs2 e)
    {
        int customerId;
        int.TryParse(hfCustomerId.Value, out customerId);
        LoadData(customerId);
    }

    private void LoadData(int customerId)
    {
        
        if (customerId > 0)
        {
            CustomerDemoDataSource.TypedView =
            IndividualDemographicsTypedView.FetchCustomerDemographicByCustomerId(customerId);
        }
        else
        {
            CustomerDemoDataSource.TypedView = new IndividualCustomerTypedView();
        }
    }

Notice that LoadData(customerId) is commented out in the ShowDemographics method. When this line is commented out, absolutely no databinding is taking place (except for the one call when the page is loaded but, the value in the hidden field isnt set yet so no data is loaded). If I un-comment the line, my control works as designed, but the databinding control provided by LLBLGen isnt used.

Here is the html code:


<table border="0" cellpadding="0" cellspacing="0" style="width: 100%">
    <tr>
        <td valign="top">
            Customer Demographics</td>
    </tr>
    <tr>
        <td>
            <asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" CellPadding="0" DataSourceID="CustomerDemoDataSource" HorizontalAlign="Left">
                <Fields>
                    <asp:BoundField DataField="CustomerId" HeaderText="CustomerId" SortExpression="CustomerId" Visible="False" />
                    <asp:BoundField DataField="DateFirstPurchase" HeaderText="Date of First Purchase" SortExpression="DateFirstPurchase" />
                    <asp:BoundField DataField="TotalPurchaseYtd" HeaderText="TotalPurchaseYtd" SortExpression="Total Purchase Amount Ytd" />
                    <asp:BoundField DataField="YearlyIncome" HeaderText="Yearly Income" SortExpression="YearlyIncome" />
                    <asp:BoundField DataField="BirthDate" HeaderText="Birth Date" SortExpression="BirthDate" />
                    <asp:BoundField DataField="Gender" HeaderText="Gender" SortExpression="Gender" />
                    <asp:BoundField DataField="Occupation" HeaderText="Occupation" SortExpression="Occupation" />
                    <asp:BoundField DataField="Education" HeaderText="Education" SortExpression="Education" />
                    <asp:BoundField DataField="TotalChildren" HeaderText="Total Children" SortExpression="TotalChildren" />
                    <asp:BoundField DataField="MaritalStatus" HeaderText="Marital Status" SortExpression="MaritalStatus" />
                    <asp:BoundField DataField="NumberChildrenAtHome" HeaderText="Number Children At Home" SortExpression="NumberChildrenAtHome" />
                    <asp:CheckBoxField DataField="HomeOwnerFlag" HeaderText="Is a Home Owner?" SortExpression="HomeOwnerFlag" />
                    <asp:BoundField DataField="NumberCarsOwned" HeaderText="Number of Cars Owned" SortExpression="NumberCarsOwned" />
                </Fields>
                <FieldHeaderStyle HorizontalAlign="Left" Wrap="False" />
            </asp:DetailsView>
            <asp:HiddenField ID="hfCustomerId" runat="server" />
        </td>
    </tr>
</table>
<llblgenpro:llblgenprodatasource2 id="CustomerDemoDataSource" runat="server" adaptertypename="Fadv.Samples.BusinessLib.DatabaseSpecific.DataAccessAdapter, Fadv.Samples.BusinessLibDBSpecific" datacontainertype="TypedView" livepersistence="False" typedviewtypename="Fadv.Samples.BusinessLib.TypedViewClasses.IndividualDemographicsTypedView, Fadv.Samples.BusinessLib" OnPerformSelect="CustomerDemoDataSource_PerformSelect" EnableViewState="False"><SelectParameters>
<asp:FormParameter Type="String" FormField="hfCustomerId" Name="customerId"></asp:FormParameter>
</SelectParameters>
</llblgenpro:llblgenprodatasource2>

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 21-Sep-2006 22:24:35   

There's not much more to tell, as datasourcecontrols like the LLBLGenProDataSourceControl all act the same: they're passively sitting on the page and they get a request for data from the bound control during the page-lifecycle, either at page creation time or when the control asks for it for example. They don't do things on their own. When sequential requests for the data come in and the datasourcecontrol finds it's the same data that's requested, there's no fetch, it's returning the cached data in the control.

So it's IMHO more a matter of when asp.net forces the controls to interact with eachother (and this is sucky documented).

Your particular case with the perform select which fires without reason, is something I've to check out, because the request for data might come in, though the datasourcecontrol should simply not fetch, but return the data already fetched.

Frans Bouma | Lead developer LLBLGen Pro
Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 22-Sep-2006 00:30:59   

Interesting. You see, my mis-interpretation was that things were handling in the opposite fashion in which you are describing. I thought (although I am not sure why) that the llblgen databound controls decided when to get data and then pushed the data into the databound control. What you are saying is that at some point in the parsing of asp.net controls they determine if they are databound, and if they are, they call into their binding source to get their data.

Do you think that if I invoke DataBind() on my datagrid, and dataview controls that it would force the LLBLGen controls interception methods to fire in a more predictable manner?

EDIT: also, just as an FYI, I am running LLBLGen 2 through the ringer because I am putting together a proposal for my client to demonstrate how LLBLGen Entities can be used in both the Web and Windows environment with no recoding. The winforms version went off without a hitch. When I am done I will send it your way so you can see it. Maybe you or someone might find it a valuable sample.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Sep-2006 08:42:51   

Yes you may try to call the control DataBind() and the DataSource.Refresh().

Also, do you have ViewState enabled in your Control? If so, try to disable it. (EnableViewState="false")

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 22-Sep-2006 11:46:29   

Devildog74 wrote:

Interesting. You see, my mis-interpretation was that things were handling in the opposite fashion in which you are describing. I thought (although I am not sure why) that the llblgen databound controls decided when to get data and then pushed the data into the databound control. What you are saying is that at some point in the parsing of asp.net controls they determine if they are databound, and if they are, they call into their binding source to get their data.

That was my understanding at first as well, but that's not the case simple_smile

Do you think that if I invoke DataBind() on my datagrid, and dataview controls that it would force the LLBLGen controls interception methods to fire in a more predictable manner?

Not sure, as the controls (like the grid/combobox etc.) already do call their own DataBind() method when the page is rendered.

EDIT: also, just as an FYI, I am running LLBLGen 2 through the ringer because I am putting together a proposal for my client to demonstrate how LLBLGen Entities can be used in both the Web and Windows environment with no recoding. The winforms version went off without a hitch. When I am done I will send it your way so you can see it. Maybe you or someone might find it a valuable sample.

Sound great! smile

Frans Bouma | Lead developer LLBLGen Pro
Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 22-Sep-2006 15:12:23   

Ok, found some fairly odd behavior taking place in ASP.NET.

I modified my original ShowDemographics code to work like this:


    public void ShowDemographics(int customerId)
    {
        hfCustomerId.Value = customerId.ToString();
        //LoadData(customerId);
        DetailsView1.DataBind();
    }

Which did nothing. In addition, changing EnableViewState didnt do anything for me either.

I have copied a the stack trace from two different entry points into the CustomerDemographics web user control. The interesting point is that on first pass DetailsView.EnsureDataBound() is called. On the post back, it isnt. The post back is comming from a link button that lives in another web user control (ClientListControl) on the same page as the CustomerDemoControl.


Call Stack Exerpt on first pass

>   App_Web_h8fafm_u.dll!UserControls_Customer_CustomerDemoControl.CustomerDemoDataSource_PerformSelect(object sender = {SD.LLBLGen.Pro.ORMSupportClasses.LLBLGenProDataSource2}, SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs2 e = {SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs2}) Line 31  C#
    SD.LLBLGen.Pro.ORMSupportClasses.NET20.DLL!SD.LLBLGen.Pro.ORMSupportClasses.LLBLGenProDataSource2. OnPerformSelect(SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs2 eventArgs = {SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs2}) + 0x2b bytes    
    SD.LLBLGen.Pro.ORMSupportClasses.NET20.DLL!SD.LLBLGen.Pro.ORMSupportClasses.LLBLGenProDataSourceView2 .ExecuteSelectTypedView(int pageSize = 0, int pageNumber = 0, System.Web.UI.DataSourceSelectArguments arguments = {System.Web.UI.DataSourceSelectArguments}) + 0x430 bytes    
    SD.LLBLGen.Pro.ORMSupportClasses.NET20.DLL!SD.LLBLGen.Pro.ORMSupportClasses.LLBLGenProDataSourceView2. ExecuteSelect(System.Web.UI.DataSourceSelectArguments arguments = {System.Web.UI.DataSourceSelectArguments}) + 0x15f bytes   
    System.Web.dll!System.Web.UI.DataSourceView.Select(System.Web.UI.DataSourceSelectArguments arguments = {System.Web.UI.DataSourceSelectArguments}, System.Web.UI.DataSourceViewSelectCallback callback = {System.Web.UI.DataSourceViewSelectCallback}) + 0x55 bytes  
    System.Web.dll!System.Web.UI.WebControls.DataBoundControl.PerformSelect() + 0x9b bytes  
    System.Web.dll!System.Web.UI.WebControls.BaseDataBoundControl.DataBind() + 0x64 bytes   
    System.Web.dll!System.Web.UI.WebControls.DetailsView.DataBind() + 0x18 bytes    
    System.Web.dll!System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() + 0x5c bytes    
    System.Web.dll!System.Web.UI.WebControls.DetailsView.EnsureDataBound() + 0xc5 bytes 
    System.Web.dll!System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls() + 0x66 bytes   
    System.Web.dll!System.Web.UI.Control.EnsureChildControls() + 0x87 bytes 
    System.Web.dll!System.Web.UI.Control.PreRenderRecursiveInternal() + 0x6e bytes  
    System.Web.dll!System.Web.UI.Control.PreRenderRecursiveInternal() + 0xea bytes  
    System.Web.dll!System.Web.UI.Control.PreRenderRecursiveInternal() + 0xea bytes  
    System.Web.dll!System.Web.UI.Control.PreRenderRecursiveInternal() + 0xea bytes  
    System.Web.dll!System.Web.UI.Control.PreRenderRecursiveInternal() + 0xea bytes  
    System.Web.dll!System.Web.UI.Control.PreRenderRecursiveInternal() + 0xea bytes  
    System.Web.dll!System.Web.UI.Page.ProcessRequestMain(bool includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint = true) + 0x1155 bytes    
    System.Web.dll!System.Web.UI.Page.ProcessRequest(bool includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint = true) + 0x70 bytes  
    System.Web.dll!System.Web.UI.Page.ProcessRequest() + 0x71 bytes 


Call Stack exerpt when CustomerList invokes CustomerDemoControl.ShowDemographics
>   App_Web_h8fafm_u.dll!UserControls_Customer_CustomerDemoControl.ShowDemographics(int customerId = 20254) Line 24 C#
    App_Web_4fcxveth.dll!UserControls_Customer_CustomerListControlTester.CustomerList_OnCustomerSelected(object sender = {ASP.usercontrols_customer_customerlist_ascx}, CustomEventArgs.CustomerSelectedCustomerEventArgs e = {CustomEventArgs.CustomerSelectedCustomerEventArgs}) Line 38 + 0x1d bytes C#
    App_Web_h8fafm_u.dll!UserControls_Customer_CustomerList.GridView1_SelectedIndexChanged(object sender = {System.Web.UI.WebControls.GridView}, System.EventArgs e = {System.EventArgs}) Line 80 + 0x26 bytes  C#
    System.Web.dll!System.Web.UI.WebControls.GridView.OnSelectedIndexChanged(System.EventArgs e = {System.EventArgs}) + 0x61 bytes  
    System.Web.dll!System.Web.UI.WebControls.GridView.HandleSelect(int rowIndex = 0) + 0x80 bytes   
    System.Web.dll!System.Web.UI.WebControls.GridView.HandleEvent(System.EventArgs e = {System.Web.UI.WebControls.GridViewCommandEventArgs}, bool causesValidation = false, string validationGroup = "") + 0xf7 bytes   
    System.Web.dll!System.Web.UI.WebControls.GridView.RaisePostBackEvent(string eventArgument = "Select$0") + 0xd6 bytes    
    System.Web.dll!System.Web.UI.WebControls.GridView.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(string eventArgument = "Select$0") + 0x20 bytes    
    System.Web.dll!System.Web.UI.Page.RaisePostBackEvent(System.Web.UI.IPostBackEventHandler sourceControl = {System.Web.UI.WebControls.GridView}, string eventArgument = "Select$0") + 0x21 bytes  
    System.Web.dll!System.Web.UI.Page.RaisePostBackEvent(System.Collections.Specialized.NameValueCollection postData) + 0xf5 bytes  
    System.Web.dll!System.Web.UI.Page.ProcessRequestMain(bool includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint = true) + 0xf00 bytes 
    System.Web.dll!System.Web.UI.Page.ProcessRequest(bool includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint = true) + 0x70 bytes  
    System.Web.dll!System.Web.UI.Page.ProcessRequest() + 0x71 bytes

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 23-Sep-2006 11:17:29   

Indeed strange...

Frans Bouma | Lead developer LLBLGen Pro