You are hereBlogs / rahul's blog / Ext.Net - Control Ids are accessible across Template Controls as Tokens

Ext.Net - Control Ids are accessible across Template Controls as Tokens


rahul's picture

By rahul - Posted on 07 April 2010

Token Ids are one of the better productive parts in the Ext.Net's (a.k.a Coolite's) server-side framework. As we know, ASP.NET translates server-side control Ids to client-side Ids that would be almost always different from their server-ids, especially if your controls are inside a Template Control, or an INamingContainer.

Ext.Net provides convenient Tokens for server control Ids (of the form #{ControlId}), that you can use inside the Handler/Fn for Listeners, and at some other places (e.g. Html/Text for labels, buttons etc), and the Ext.Net framework translates them to the control's corresponding client-side id generated by ASP.NET.

However, I recently noticed one interesting aspect of this Id translation. You know, 2 controls inside the same TemplateControl (Page and WebUserControl etc.) cannot have same ID, but IDs can be same across 2 controls in different TemplateControls, and ASP.NET generates unique client-side Ids for them. In addition, controls inside a TemplateControl can only access other controls inside the same TemplateControl directly by using the ID property.

And I thought the same would hold for Ext.Net. That is, when you use #{ControlId} tokens, it always refers to the control with the specified Id from the same Template control.

However, while working recently, I observed one exception to this. Suppose a Page registers & uses 2 UserControls UC1 & UC2 on it. Further, both UC1 & UC2 have a control with Id "Control1", but only UC1 has a control with Id "Control2".

In the above scenario, using #{Control1} from UC1 would refer to the control inside UC1, and ditto for UC2. No surprises here. Similarly, using #{Control2} from UC1 would again refer to the local control in UC1.

But if you use #{Control2} from UC2 (which remember does not have any control with this server Id), Ext.Net makes it reference to the control with that Id from UC1.

Confused, well let me put this in words. When using Token Id inside a Template Control, Ext.Net first tries to reference it from the local Template Control itself. However, if this fails (meaning there is no control with the specified Id in the same Template Control), Ext.Net tries to bind it to a control from another Template Control registered on the same page (or from the Page itself), with the same Id as that inside the Token.

Cool, you have to agree... But simultaneously undocumented and I am not sure whether this is an intentional feature, or a unknown side-effect.

The attached code demonstrates what I am trying to say in this blog post.

UPDATE:

  • (Apr 12, 2010) - The same concept applies to cross-referenced Control Ids. e.g. In data controls like GridPanel, Combobox etc., you specify the source Store for data using StoreID. Ext.Net searches for a store with the specified ID first in the same Template control, and if it does not find one, continues with the search in the Parent or sibling Template controls.
  • As specified by vlad below, you can use the IDMode property to control how server Ids are translated into client Ids. The better part of it is that the Tokens automatically adjust to the specified IDMode for the control. Thus, if Control1 has IDMode as Static, #{Control1} translates to "Control1", but if IDMode for the Control1 is Legacy, it would translate into "ctlxx_Control1" or something like that depending upon the INamingContainer hierarchy the control is in.
AttachmentSize
ControlIds.zip1.34 KB

Ext.Net searches nearest control. If current scope (and its children) doesn't have required control then Ext.Net goes up and perform search for parent control siblings and so on

Also each Ext.Net control has IDMode property which define ID generation strategy:

Inherit - Inherits the IDMode for the Parent. This is the default functionality of all Ext.Net Components.

Legacy - Legacy functionality for generating CliendID's. No change from default ASP.NET functionality.

Static - Render the "id" property in the client as exactly the value set. Developer must manually ensure client-side ID uniqueness.
Ignore -  Do not render the "id" property in the client. 
Explicit -  Only render the "id" property if the .ID is explicitly set, otherwise renders as the ClientID if autogenerated by the ASP.NET runtime.
ExplicitClientID - Only render the ClientID property if the .ID is explicitly set.
For example, you can set IDMode="Explicit", it will force ID rendering instead ClientID even if control is placed inside INamingContainer (if you define ID manually)
Also there are three levels of IDMode: global (from web.config or Session), page level (from ResourceManager) and local (controls property). Local level has highest priority, page level can overrides global level
rahul's picture

Hmmm, after vlad's reply, I went back and re-read the blog post to notice that I forgot mentioning Ext.Net's useful IDMode enumeration (which was on my mind as I was writing the post, just fumbled it up somewhere).

So, vlad's reply adds 2 more important points to the blog post:

  1. The situation I discussed in the blog post is officially supported from Ext.Net team, and we can rely on it being available as a feature.
  2. This feature complements the IDMode property, i.e. the Client Id substituted for the token #{ControlId} would be decided appropriately based upon the value of IDMode property for the control (Static, Legacy etc.)

Thanks for adding value to the blog vlad!!!

Post new comment

The content of this field is kept private and will not be shown publicly.
Type the characters you see in this picture. (verify using audio)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.

Recent comments