Naming container

Discussion in 'ASP .Net Building Controls' started by Jonas Auken, Jul 28, 2004.

  1. Jonas Auken

    Jonas Auken Guest

    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
    Jonas Auken, Jul 28, 2004
    #1
    1. Advertising

  2. 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.)
    Steven Cheng[MSFT], Jul 29, 2004
    #2
    1. Advertising

  3. Jonas Auken

    Jonas Auken Guest

    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[MSFT]" <> wrote in message
    news:eek:jEEs$...
    > 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.)
    >
    >
    >
    Jonas Auken, Jul 29, 2004
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    6,471
  2. Harman
    Replies:
    1
    Views:
    2,494
    Moiristo
    Jul 28, 2006
  3. Monty
    Replies:
    7
    Views:
    427
    Walter Wang [MSFT]
    Dec 10, 2007
  4. cmoore
    Replies:
    1
    Views:
    197
    Felix Wu [MSFT]
    Sep 11, 2003
  5. Monty

    Naming Container difference between VS2003 and VS2005

    Monty, Dec 4, 2007, in forum: ASP .Net Building Controls
    Replies:
    1
    Views:
    804
    Monty
    Dec 4, 2007
Loading...

Share This Page