Naming container

J

Jonas Auken

I'm having a problem with a linkbutton which is not assigned a UniqueID with
all the prefixes for some reason.

The linkbutton resides in a UserControl but is used within a custom control;
both controls implement the INamingContainer.

The strangest thing is, when I click this linkbutton on a page, it's event
is caught and all of a sudden it has a name - why? and from where?

the problem is i need the name before the event phase - more specifically in
the page_load phase - to see if the button has been clicked or not.. is
there a solution; or perhaps a workaround? can I force the name upon the
linkbutton (as it appearently is done later in the lifecycle of the page) or
can I somehow string it together myself?

hope any of this makes sense, cause I'm pretty desperate by now!

/jonas
 
S

Steven Cheng[MSFT]

Hi Jonas,

From your description, you're using a LinkButton control nested in another
container control(Usercontrol or custom control) which implement
INamingContainer. And now you found this will make the LinkButton be auto
generate a name attribute and currently you want to get this value so that
you can check whether the linkbutton is clicked(before its click event
handler be called) when th page is posted back ,yes?

As for this problem, here are my suggetions:
1. Generally all the controls which will be rendered as an <Input type=...>
html element will contains a "name" attirbute, this is used to identify
them in the request's Form collection when the page is submit and post
back. And by default, the "name" attribute's value willl be similiar with
the "id"'s value(I means the id render out to the client), you may have a
test and view the page's source at the clientside to verfiy this.

2. As for the controls nested in other container controls which has
implemented INamingContainer inteface, their ClientID(the actual Id be
rendered to client) will be composited by its own id and its parent
container's id. Also, its name attribute is the same(is not the same with
its serverside control id). You can use the "ClientID" property to get its
actual id, but the "name" attribute will be a bit different , because the
split flag are different, for example:
if the id rendered out is
UserControl_LinkButton1, then the name of it will be
UserControl:LinkButton1

3. When the linkbutton is clicked , it'll actually call the __doPostBack()
client script (auto genreated by the asp.net). You can view the page's
source in the clientside to have a look at the "__doPostBack" function's
code , that will tell you how to "name" of the linkbutton is generated on
the fly.
Here is the code i pull from the page source:
============================
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
theform = document.Form1;
}
else {
theform = document.forms["Form1"];
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}

=============================
Then, in the serverside , we can use the "__EVENTTARGET" argument to get
the linkbutton's "name" which is posted back. It use the
" theform.__EVENTTARGET.value = eventTarget.split("$").join(":");"

to change all the "$" to ":", that's the acutal value you can check in the
Request.Form collecdtion at serverside.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

Jonas Auken

hi Steven,

that will definitely work - thank you very much. only small problem is, that
i cannot use the unique name of the linkbutton - only it's id, to see if it
has been clicked - and since i'm bound to run into a situation where this is
relevant, i might as well ask now..

the linkbuttons unique id (as sent to the client) is:
_ctl5:_ctl5:_ctl0:_ctl0:Hint1:lnkText
- i will split this string and compare the last bit with the linkbuttons id
to see if it is indeed this button, which has been clicked - so far so good.

the problem i still have (as far as i can see) actually is that the control
tree is not built properly in before page_load, but for some reason has been
built by the engine by the time events are handled (ie. prerender):
The linkbutton's parent is a class called Target. This object does not have
a parent in page_load - but when we reach prerender it has! This parent is a
control we have made ourselves - and hence it is properly not correct. The
aspx code for using it looks like this:

<%@ Register TagPrefix="cw" Namespace="Csite.Web" Assembly="CsiteWeb" %>
<cw:hint id="Hint1" runat="server">
<cw:Target id="cTarget">
<td>
<asp:imagebutton id="lnkImage" CssClass="soegtab"
Runat="server"></asp:imagebutton>
<asp:linkbutton id="lnkText" CssClass="soegtab"
Runat="server"></asp:linkbutton>
</td>
</cw:Target>
<cw:Source>
<div class="hintClass">
Klik "Din profil" for at vælge<br />denne søgemetode som standard.
</div>
</cw:Source>
</cw:hint>

The Target class has ParseChildren(false) and the following method for
adding children:
protected override void AddParsedSubObject(object obj) {
if (obj is System.Web.UI.Control) {
Controls.Add((Control)obj);
}
}

Is has no CreateChildControls method.

The Hint class has ParseChildren(true,"Settings"), which puts Source and
Target objects into a collection - these are add to Controls in this method:
protected override void CreateChildControls() {
Controls.Clear();
if (SourceTemplate != null) {
Controls.Add(SourceTemplate);
}
if (TargetTemplate != null) {
Controls.Add(TargetTemplate);
}
}

SourceTemplate looks like this:
public Source SourceTemplate{
get {
if (settings != null) {
foreach (HintSetting s in Settings) {
if (s is Source) {
return s as Source;
}
}
}
return null;
}
}

and settings:
[
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public HintSettingCollection Settings
{
get
{
if (settings == null)
{
settings = new HintSettingCollection();
if (IsTrackingViewState)
{
((IStateManager)settings).TrackViewState();
}
}
return settings;
}
}

Can you explain why the control tree behaves like this? What are we doing
wrong?

I hope all this code makes things clearer - I must admit I do not see the
full picture ;)
And I hope you can help..

Sincerely,
Jonas Auken


Steven Cheng said:
Hi Jonas,

From your description, you're using a LinkButton control nested in another
container control(Usercontrol or custom control) which implement
INamingContainer. And now you found this will make the LinkButton be auto
generate a name attribute and currently you want to get this value so that
you can check whether the linkbutton is clicked(before its click event
handler be called) when th page is posted back ,yes?

As for this problem, here are my suggetions:
1. Generally all the controls which will be rendered as an <Input type=...>
html element will contains a "name" attirbute, this is used to identify
them in the request's Form collection when the page is submit and post
back. And by default, the "name" attribute's value willl be similiar with
the "id"'s value(I means the id render out to the client), you may have a
test and view the page's source at the clientside to verfiy this.

2. As for the controls nested in other container controls which has
implemented INamingContainer inteface, their ClientID(the actual Id be
rendered to client) will be composited by its own id and its parent
container's id. Also, its name attribute is the same(is not the same with
its serverside control id). You can use the "ClientID" property to get its
actual id, but the "name" attribute will be a bit different , because the
split flag are different, for example:
if the id rendered out is
UserControl_LinkButton1, then the name of it will be
UserControl:LinkButton1

3. When the linkbutton is clicked , it'll actually call the __doPostBack()
client script (auto genreated by the asp.net). You can view the page's
source in the clientside to have a look at the "__doPostBack" function's
code , that will tell you how to "name" of the linkbutton is generated on
the fly.
Here is the code i pull from the page source:
============================
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
theform = document.Form1;
}
else {
theform = document.forms["Form1"];
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}

=============================
Then, in the serverside , we can use the "__EVENTTARGET" argument to get
the linkbutton's "name" which is posted back. It use the
" theform.__EVENTTARGET.value = eventTarget.split("$").join(":");"

to change all the "$" to ":", that's the acutal value you can check in the
Request.Form collecdtion at serverside.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top