Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > ASP .Net > ASP .Net Datagrid Control > Nested datagrids -- events not handled correctly

Reply
Thread Tools

Nested datagrids -- events not handled correctly

 
 
Steve Hershoff
Guest
Posts: n/a
 
      08-27-2006
Hi everyone,

I've got a strange one here. There are two datagrids on my page, one nested
within the other. I'll refer to them as the topmost and secondary
datagrids.

In the topmost datagrid's OnItemDataBound() method we check for the row in
which it's appropriate to add the secondary datagrid. Exactly one row in
the topmost grid will contain the secondary grid.

When we do find the appropriate row in the topmost grid, we add to one of
its cells a DropDownList and then our secondary datagrid. Meanwhile, within
this secondary datagrid we add a LinkButton to one of its cells, for
specific rows. Not all rows of the secondary grid get a button. We use the
ItemEvent() method to check.

When we add the DropDownList and LinkButtons, we create event handlers for
their SelectedIndexChanged() and Click() events, respectively. Now comes my
problem.

What's strange is that when I click on one of the LinkButtons the page is
reloaded (as expected), but then the DropDownList's SelectedIndexChanged()
handler is fired. I never touched the DropDownList however.

What's more, if I fail to call the secondary datagrid's DataBind() method
from within this DropDownList event handler, the LinkButton's Click()
handler is never called-- even though that's the control I clicked on to
start the chain of events!

So I'm confused to say the least. I realize this stuff can be tricky and
I'm not expecting a total answer to my problem, but does any of this ring a
bell? Specifically, why is the DropDownList's event handler being fired
when the LinkButton is clicked, and why is the LinkButton's Click() handler
never called unless the DropDownList's event handler calls the secondary
datagrid's BindData() method?

Thanks very much.


 
Reply With Quote
 
 
 
 
Tim_Mac
Guest
Posts: n/a
 
      08-28-2006
hi steve,

here is a good article on this re-occuring question:
http://odetocode.com/Blogs/scott/arc...7/19/5365.aspx

when you create a control programatically like you do in your code, you need
to fully re-create it for each postback. otherwise your event is going to
be raised for a control that doesn't exist, since each post back is its own
separate entity. this is why the click event doesn't happen unless you
re-bind the datagrid.

strange that the SelectedIndexChanged event is fired, did you try debugging
to see what the call stack is like when that event is triggered. this will
help you track whether it is in response to some of your own code. can you
post your code for databinding the drop down list?

tim

------------------------------------------
blog: http://tim.mackey.ie
"Steve Hershoff" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi everyone,
>
> I've got a strange one here. There are two datagrids on my page, one
> nested within the other. I'll refer to them as the topmost and secondary
> datagrids.
>
> In the topmost datagrid's OnItemDataBound() method we check for the row in
> which it's appropriate to add the secondary datagrid. Exactly one row in
> the topmost grid will contain the secondary grid.
>
> When we do find the appropriate row in the topmost grid, we add to one of
> its cells a DropDownList and then our secondary datagrid. Meanwhile,
> within this secondary datagrid we add a LinkButton to one of its cells,
> for specific rows. Not all rows of the secondary grid get a button. We
> use the ItemEvent() method to check.
>
> When we add the DropDownList and LinkButtons, we create event handlers for
> their SelectedIndexChanged() and Click() events, respectively. Now comes
> my problem.
>
> What's strange is that when I click on one of the LinkButtons the page is
> reloaded (as expected), but then the DropDownList's SelectedIndexChanged()
> handler is fired. I never touched the DropDownList however.
>
> What's more, if I fail to call the secondary datagrid's DataBind() method
> from within this DropDownList event handler, the LinkButton's Click()
> handler is never called-- even though that's the control I clicked on to
> start the chain of events!
>
> So I'm confused to say the least. I realize this stuff can be tricky and
> I'm not expecting a total answer to my problem, but does any of this ring
> a bell? Specifically, why is the DropDownList's event handler being fired
> when the LinkButton is clicked, and why is the LinkButton's Click()
> handler never called unless the DropDownList's event handler calls the
> secondary datagrid's BindData() method?
>
> Thanks very much.
>



 
Reply With Quote
 
 
 
 
Steve Hershoff
Guest
Posts: n/a
 
      08-28-2006
Hi Tim,

Thanks for your note, and for the links. When the SelectedIndexChanged
event is fired it's the only element in the call stack, aside from the
ubiquitious <Non User Code> portion below it.

Here's the code used for creating the dropdown. It's called in the OnInit()
method of the web control (this is all contained in an ascx file):

this.ddl_Transaction_Filt = new DropDownList();
this.ddl_Transaction_Filt.Items.Add(new ListItem("Taken", "TAKEN"));
this.ddl_Transaction_Filt.Items.Add(new ListItem("Accrued", "ACCR"));
this.ddl_Transaction_Filt.Items.Add(new ListItem("Adjusted", "ADJ"));
this.ddl_Transaction_Filt.Items.Add(new ListItem("All", "ALL"));
this.ddl_Transaction_Filt.CssClass = "Normal";
this.ddl_Transaction_Filt.AutoPostBack = true;
this.ddl_Transaction_Filt.SelectedIndexChanged += new
System.EventHandler(this.ddl_Transaction_Filt_Sele ctedIndexChanged);

....as you can tell, the dropdown is hard-coded.

Here's something interesting: later on in the OnInit() method I compare a
session variable with the value in that dropdown list. If the session
variable and the value in the dropdown differ I set the index in the
dropdown appropriately.

The guy who worked on this page before me made a mistake in the code and
mixed up the "ADJ" and "ALL" bits. The result being the dropdown's index
changes on every page load, which means the secondary datagrid is bound
every page load, which also means (it appears) the LinkButton's click event
is handled when needed. If I "fix" his code so the dropdown works correctly
the LinkButton no longer works.



"Tim_Mac" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> hi steve,
>
> here is a good article on this re-occuring question:
> http://odetocode.com/Blogs/scott/arc...7/19/5365.aspx
>
> when you create a control programatically like you do in your code, you
> need to fully re-create it for each postback. otherwise your event is
> going to be raised for a control that doesn't exist, since each post back
> is its own separate entity. this is why the click event doesn't happen
> unless you re-bind the datagrid.
>
> strange that the SelectedIndexChanged event is fired, did you try
> debugging to see what the call stack is like when that event is triggered.
> this will help you track whether it is in response to some of your own
> code. can you post your code for databinding the drop down list?
>
> tim
>
> ------------------------------------------
> blog: http://tim.mackey.ie
> "Steve Hershoff" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> Hi everyone,
>>
>> I've got a strange one here. There are two datagrids on my page, one
>> nested within the other. I'll refer to them as the topmost and secondary
>> datagrids.
>>
>> In the topmost datagrid's OnItemDataBound() method we check for the row
>> in which it's appropriate to add the secondary datagrid. Exactly one row
>> in the topmost grid will contain the secondary grid.
>>
>> When we do find the appropriate row in the topmost grid, we add to one of
>> its cells a DropDownList and then our secondary datagrid. Meanwhile,
>> within this secondary datagrid we add a LinkButton to one of its cells,
>> for specific rows. Not all rows of the secondary grid get a button. We
>> use the ItemEvent() method to check.
>>
>> When we add the DropDownList and LinkButtons, we create event handlers
>> for their SelectedIndexChanged() and Click() events, respectively. Now
>> comes my problem.
>>
>> What's strange is that when I click on one of the LinkButtons the page is
>> reloaded (as expected), but then the DropDownList's
>> SelectedIndexChanged() handler is fired. I never touched the
>> DropDownList however.
>>
>> What's more, if I fail to call the secondary datagrid's DataBind() method
>> from within this DropDownList event handler, the LinkButton's Click()
>> handler is never called-- even though that's the control I clicked on to
>> start the chain of events!
>>
>> So I'm confused to say the least. I realize this stuff can be tricky and
>> I'm not expecting a total answer to my problem, but does any of this ring
>> a bell? Specifically, why is the DropDownList's event handler being
>> fired when the LinkButton is clicked, and why is the LinkButton's Click()
>> handler never called unless the DropDownList's event handler calls the
>> secondary datagrid's BindData() method?
>>
>> Thanks very much.
>>

>
>



 
Reply With Quote
 
Tim_Mac
Guest
Posts: n/a
 
      08-28-2006
hi steve, i'm trying to piece together the setup there.

so the drop-down-list SelectedIndexChanged event fires because of your code
that compares the session variable and updates the SelectedIndex of the menu
accordingly. that one is explained then?

if you only bind the secondary datagrid in response to a
SelectedIndexChanged event, then the LinkButton Click event won't fire for
that datagrid. you need to bind the secondary datagrid for each post back
where you want to use events with it (especially on the Postback that occurs
when you click the LinkButton).

you're code should look something like this:

public void Page_Load(...)
{
if(!IsPostBack)
{
// bind the topmost datagrid and other first time load stuff
}
else
{
// bind the secondary datagrid, dropdownlist, extra button
column, etc.
// exactly as you had it as of the last postback
}
}

this approach works for me. if this doesn't give you any ideas, can you
post your Page_Load and OnInit code, and anything else that affects the
loading/binding of the dynamic controls. if it's worth it, you may like to
create a stripped down version of the page and i could test it out here.

cheers.
tim


 
Reply With Quote
 
Steve Hershoff
Guest
Posts: n/a
 
      08-29-2006
Thanks again Tim. You understand how the dropdown list and the session
variable interact.

I guess I need to play around a little more. I suppose the way things work
is that when I click the LinkButton a postback is generated, then the
Page_Load is called. I assumed the LinkButton's Click() event handler would
be called even if the datagrid it resides in isn't bound again, but it
appears not?

One more thing, if you don't mind another question. Would you happen to
know what events are fired or what happens in general on a page when a
DataBind takes place? I ask because in our Page_Load we're binding the
topmost datagrid every time, whether IsPostBack is true or not.

The first time we enter this page the topmost grid is bound only once. If I
click on a hyperlink to "show the secondary datagrid," the Page_Load method
is called again, with IsPostBack set to true. So far so good. Again,
Page_Load binds the master datagrid.

However, this time the page is immediately reloaded(?) (IsPostBack equals
false now) and the master datagrid is bound yet again. Only now is the
secondary datagrid loaded and bound.

I don't understand why Page_Load is called twice in succession? I'm not
reloading or redirecting back to the page, at least not directly in my code.
Strange indeed.

I keep trying to find good information on the page lifecycle. The
4guysfromrolla.com site is great for workaday questions involving aspx, but
it's still tough. No two sources seem to agree on what happens. Either
that or they flood you with terms like PagePreRenderInit() and set your head
spinning. Do you happen to have any favored websites or books that do a
good job on this?

Thanks again for all your help. I really appreciate it.

-Steve.




"Tim_Mac" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> hi steve, i'm trying to piece together the setup there.
>
> so the drop-down-list SelectedIndexChanged event fires because of your
> code that compares the session variable and updates the SelectedIndex of
> the menu accordingly. that one is explained then?
>
> if you only bind the secondary datagrid in response to a
> SelectedIndexChanged event, then the LinkButton Click event won't fire for
> that datagrid. you need to bind the secondary datagrid for each post back
> where you want to use events with it (especially on the Postback that
> occurs when you click the LinkButton).
>
> you're code should look something like this:
>
> public void Page_Load(...)
> {
> if(!IsPostBack)
> {
> // bind the topmost datagrid and other first time load stuff
> }
> else
> {
> // bind the secondary datagrid, dropdownlist, extra button
> column, etc.
> // exactly as you had it as of the last postback
> }
> }
>
> this approach works for me. if this doesn't give you any ideas, can you
> post your Page_Load and OnInit code, and anything else that affects the
> loading/binding of the dynamic controls. if it's worth it, you may like
> to create a stripped down version of the page and i could test it out
> here.
>
> cheers.
> tim
>



 
Reply With Quote
 
Tim_Mac
Guest
Posts: n/a
 
      08-29-2006
hi Steve,
you're welcome, glad to help out.

you only need to bind the topmost datagrid for the first postback. the
reason for this is because it is a statically declared control in the aspx,
and the viewstate is enough to maintain its state across postbacks.
however, if you change the underlying data, i.e. run an update/delete SQL
query, then you will need to re-bind the datagrid afterwards because the
viewstate data will not reflect your data changes.

the reason your events are getting lost for the secondary datagrid is
because this control does not exist for any given postback unless it is
programatically created exactly as it was previously. does that make sense?

re: events for a DataBind()... i'm not aware of any knock-on events raised
by calling DataBind on a control. if you set a breakpoint at the DataBind
call, and hit F11 you will step into any user code that runs as a result of
calling Databind.

i know what you mean about the complexity of the Page lifecycle. i
generally don't concern myself with such events, except obviously Page_Load.
there is lots of opinion on where/when to create your dynamic controls.
Personally i like to do it all in Page_Load because it is very clear then
what is going on, you don't need to worry about the order of events.
Page_Load will always run first, and then any events will fire after that.
advanced users may say this is too simplistic, but i have done plenty of
complex scenarios containing nested dynamic controls only using Page_Load.

the official resource on the Page/Postback lifecycle is on MSDN2:
http://msdn2.microsoft.com/en-us/library/ms178472.aspx
this really is an excellent article and it is the one i was looking for
earlier but couldn't find. well worth an afternoon of studying. they also
give a few tips for nested databound controls under the heading "catch up
events"

i am stumped by the double Page_Load. i can't see how Page.Postback could
be false unless you have some Response.Redirect code or some javascript to
reload the page, or if your linkbutton doesn't directly cause a postback.
i.e. if it is rendered as <a href="SamePage.aspx?Select=10">Select</a>

can you post the aspx and code-behind? don't worry about the database
connections etc, just by looking at the code it may be clear where the
problem is.

thanks
tim

"Steve Hershoff" <(E-Mail Removed)> wrote in message
news:OnV$(E-Mail Removed)...
> Thanks again Tim. You understand how the dropdown list and the session
> variable interact.
>
> I guess I need to play around a little more. I suppose the way things
> work is that when I click the LinkButton a postback is generated, then the
> Page_Load is called. I assumed the LinkButton's Click() event handler
> would be called even if the datagrid it resides in isn't bound again, but
> it appears not?
>
> One more thing, if you don't mind another question. Would you happen to
> know what events are fired or what happens in general on a page when a
> DataBind takes place? I ask because in our Page_Load we're binding the
> topmost datagrid every time, whether IsPostBack is true or not.
>
> The first time we enter this page the topmost grid is bound only once. If
> I click on a hyperlink to "show the secondary datagrid," the Page_Load
> method is called again, with IsPostBack set to true. So far so good.
> Again, Page_Load binds the master datagrid.
>
> However, this time the page is immediately reloaded(?) (IsPostBack equals
> false now) and the master datagrid is bound yet again. Only now is the
> secondary datagrid loaded and bound.
>
> I don't understand why Page_Load is called twice in succession? I'm not
> reloading or redirecting back to the page, at least not directly in my
> code. Strange indeed.
>
> I keep trying to find good information on the page lifecycle. The
> 4guysfromrolla.com site is great for workaday questions involving aspx,
> but it's still tough. No two sources seem to agree on what happens.
> Either that or they flood you with terms like PagePreRenderInit() and set
> your head spinning. Do you happen to have any favored websites or books
> that do a good job on this?
>
> Thanks again for all your help. I really appreciate it.
>
> -Steve.
>
>
>
>
> "Tim_Mac" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> hi steve, i'm trying to piece together the setup there.
>>
>> so the drop-down-list SelectedIndexChanged event fires because of your
>> code that compares the session variable and updates the SelectedIndex of
>> the menu accordingly. that one is explained then?
>>
>> if you only bind the secondary datagrid in response to a
>> SelectedIndexChanged event, then the LinkButton Click event won't fire
>> for that datagrid. you need to bind the secondary datagrid for each post
>> back where you want to use events with it (especially on the Postback
>> that occurs when you click the LinkButton).
>>
>> you're code should look something like this:
>>
>> public void Page_Load(...)
>> {
>> if(!IsPostBack)
>> {
>> // bind the topmost datagrid and other first time load stuff
>> }
>> else
>> {
>> // bind the secondary datagrid, dropdownlist, extra button
>> column, etc.
>> // exactly as you had it as of the last postback
>> }
>> }
>>
>> this approach works for me. if this doesn't give you any ideas, can you
>> post your Page_Load and OnInit code, and anything else that affects the
>> loading/binding of the dynamic controls. if it's worth it, you may like
>> to create a stripped down version of the page and i could test it out
>> here.
>>
>> cheers.
>> tim
>>

>
>



 
Reply With Quote
 
Steve Hershoff
Guest
Posts: n/a
 
      08-30-2006
Good call on the double page_load, Tim. The "show secondary datagrid" link
does indeed lead to a response.redirect, so that should explain things
there. I'd be glad to post the code-behind info, but I think you've got me
on the right direction.

I'll definitely check out that MSDN2 link you posted on the page lifecycle.
I've had it with guesswork on what gets fired and when!

Indebted as always,

-Steve

"Tim_Mac" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> hi Steve,
> you're welcome, glad to help out.
>
> you only need to bind the topmost datagrid for the first postback. the
> reason for this is because it is a statically declared control in the
> aspx, and the viewstate is enough to maintain its state across postbacks.
> however, if you change the underlying data, i.e. run an update/delete SQL
> query, then you will need to re-bind the datagrid afterwards because the
> viewstate data will not reflect your data changes.
>
> the reason your events are getting lost for the secondary datagrid is
> because this control does not exist for any given postback unless it is
> programatically created exactly as it was previously. does that make
> sense?
>
> re: events for a DataBind()... i'm not aware of any knock-on events raised
> by calling DataBind on a control. if you set a breakpoint at the DataBind
> call, and hit F11 you will step into any user code that runs as a result
> of calling Databind.
>
> i know what you mean about the complexity of the Page lifecycle. i
> generally don't concern myself with such events, except obviously
> Page_Load. there is lots of opinion on where/when to create your dynamic
> controls. Personally i like to do it all in Page_Load because it is very
> clear then what is going on, you don't need to worry about the order of
> events. Page_Load will always run first, and then any events will fire
> after that. advanced users may say this is too simplistic, but i have done
> plenty of complex scenarios containing nested dynamic controls only using
> Page_Load.
>
> the official resource on the Page/Postback lifecycle is on MSDN2:
> http://msdn2.microsoft.com/en-us/library/ms178472.aspx
> this really is an excellent article and it is the one i was looking for
> earlier but couldn't find. well worth an afternoon of studying. they
> also give a few tips for nested databound controls under the heading
> "catch up events"
>
> i am stumped by the double Page_Load. i can't see how Page.Postback could
> be false unless you have some Response.Redirect code or some javascript to
> reload the page, or if your linkbutton doesn't directly cause a postback.
> i.e. if it is rendered as <a href="SamePage.aspx?Select=10">Select</a>
>
> can you post the aspx and code-behind? don't worry about the database
> connections etc, just by looking at the code it may be clear where the
> problem is.
>
> thanks
> tim
>
> "Steve Hershoff" <(E-Mail Removed)> wrote in message
> news:OnV$(E-Mail Removed)...
>> Thanks again Tim. You understand how the dropdown list and the session
>> variable interact.
>>
>> I guess I need to play around a little more. I suppose the way things
>> work is that when I click the LinkButton a postback is generated, then
>> the Page_Load is called. I assumed the LinkButton's Click() event
>> handler would be called even if the datagrid it resides in isn't bound
>> again, but it appears not?
>>
>> One more thing, if you don't mind another question. Would you happen to
>> know what events are fired or what happens in general on a page when a
>> DataBind takes place? I ask because in our Page_Load we're binding the
>> topmost datagrid every time, whether IsPostBack is true or not.
>>
>> The first time we enter this page the topmost grid is bound only once.
>> If I click on a hyperlink to "show the secondary datagrid," the Page_Load
>> method is called again, with IsPostBack set to true. So far so good.
>> Again, Page_Load binds the master datagrid.
>>
>> However, this time the page is immediately reloaded(?) (IsPostBack equals
>> false now) and the master datagrid is bound yet again. Only now is the
>> secondary datagrid loaded and bound.
>>
>> I don't understand why Page_Load is called twice in succession? I'm not
>> reloading or redirecting back to the page, at least not directly in my
>> code. Strange indeed.
>>
>> I keep trying to find good information on the page lifecycle. The
>> 4guysfromrolla.com site is great for workaday questions involving aspx,
>> but it's still tough. No two sources seem to agree on what happens.
>> Either that or they flood you with terms like PagePreRenderInit() and set
>> your head spinning. Do you happen to have any favored websites or books
>> that do a good job on this?
>>
>> Thanks again for all your help. I really appreciate it.
>>
>> -Steve.
>>
>>
>>
>>
>> "Tim_Mac" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>>> hi steve, i'm trying to piece together the setup there.
>>>
>>> so the drop-down-list SelectedIndexChanged event fires because of your
>>> code that compares the session variable and updates the SelectedIndex of
>>> the menu accordingly. that one is explained then?
>>>
>>> if you only bind the secondary datagrid in response to a
>>> SelectedIndexChanged event, then the LinkButton Click event won't fire
>>> for that datagrid. you need to bind the secondary datagrid for each
>>> post back where you want to use events with it (especially on the
>>> Postback that occurs when you click the LinkButton).
>>>
>>> you're code should look something like this:
>>>
>>> public void Page_Load(...)
>>> {
>>> if(!IsPostBack)
>>> {
>>> // bind the topmost datagrid and other first time load stuff
>>> }
>>> else
>>> {
>>> // bind the secondary datagrid, dropdownlist, extra button
>>> column, etc.
>>> // exactly as you had it as of the last postback
>>> }
>>> }
>>>
>>> this approach works for me. if this doesn't give you any ideas, can you
>>> post your Page_Load and OnInit code, and anything else that affects the
>>> loading/binding of the dynamic controls. if it's worth it, you may like
>>> to create a stripped down version of the page and i could test it out
>>> here.
>>>
>>> cheers.
>>> tim
>>>

>>
>>

>
>



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Events from dynamic checkboxes sometimes handled the wrong way galien8@zonnet.nl ASP .Net 0 08-13-2008 04:08 PM
Can a Menu Control (ASP.NET 2.0) events be handled in javascript SaikiranPuppala ASP .Net 0 07-11-2008 05:37 AM
Nested datagrids -- events not handled correctly Steve Hershoff ASP .Net 6 08-30-2006 12:20 AM
Nested Datagrids Events Question seal ASP .Net Datagrid Control 1 03-23-2006 02:59 AM
Events Events Events Please Help Chris ASP .Net Web Controls 0 08-30-2005 08:21 PM



Advertisments