By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,717 Members | 2,069 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,717 IT Pros & Developers. It's quick & easy.

Nested datagrids -- events not handled correctly

P: n/a
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.
Aug 27 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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" <ba******@nowhere.comwrote in message
news:Ob**************@TK2MSFTNGP06.phx.gbl...
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.

Aug 28 '06 #2

P: n/a
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 Codeportion 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" <ti********@community.nospamwrote in message
news:Og**************@TK2MSFTNGP03.phx.gbl...
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" <ba******@nowhere.comwrote in message
news:Ob**************@TK2MSFTNGP06.phx.gbl...
>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.


Aug 28 '06 #3

P: n/a
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
Aug 28 '06 #4

P: n/a
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" <ti********@community.nospamwrote in message
news:uy*************@TK2MSFTNGP06.phx.gbl...
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

Aug 29 '06 #5

P: n/a
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" <ba******@nowhere.comwrote in message
news:On**************@TK2MSFTNGP05.phx.gbl...
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" <ti********@community.nospamwrote in message
news:uy*************@TK2MSFTNGP06.phx.gbl...
>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


Aug 29 '06 #6

P: n/a
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" <ti********@community.nospamwrote in message
news:ek**************@TK2MSFTNGP02.phx.gbl...
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" <ba******@nowhere.comwrote in message
news:On**************@TK2MSFTNGP05.phx.gbl...
>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" <ti********@community.nospamwrote in message
news:uy*************@TK2MSFTNGP06.phx.gbl...
>>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



Aug 30 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.