Jan 16, 2009, 9:52 AM
#{referencing} UserControls
Hey, using Coolite for the first time on a project and it's pretty exciting.
I use UserControls pretty extensively as sort of "pre-configured" Controls (like bundling a Window and it's children in a user control for re-use). But then it's difficult to reference the Ext client objects them from parent controls, especially from a Handler attribute where you can't use <%= Mywindow.ClientID %> idiom.
One thing I've added to the code on my end is an IClientReferenceProvider interface that provides a hook into the TokenUtils.ReplaceIDTokens() method:
MyUserControl.ascx
I use UserControls pretty extensively as sort of "pre-configured" Controls (like bundling a Window and it's children in a user control for re-use). But then it's difficult to reference the Ext client objects them from parent controls, especially from a Handler attribute where you can't use <%= Mywindow.ClientID %> idiom.
One thing I've added to the code on my end is an IClientReferenceProvider interface that provides a hook into the TokenUtils.ReplaceIDTokens() method:
public static string ReplaceIDTokens(string script, Control seed)
{
Regex regex = new Regex(TokenUtils.IDPattern);
MatchCollection matches = regex.Matches(script);
Control control = null;
string id = "";
foreach (Match match in matches)
{
id = match.Value.Remove(match.Value.Length - 1).Remove(0, 2);
control = ControlUtils.FindControl(seed, id);
if (control != null)
{
if (control is Observable)
{
script = script.Replace(match.Value, control.ClientID);
} // ADDED
else if (control is IClientReferenceProvider)
{
script = script.Replace(match.Value, ((IClientReferenceProvider)control).GetClientReference());
} // END ADDED
else
{
script = script.Replace(match.Value, string.Concat("Ext.get(\"", control.ClientID, "\")"));
}
}
else
{
script = script.Replace(match.Value, string.Concat("Ext.get(\"", match.Value.Remove(match.Value.Length - 1).Remove(0, 2), "\")"));
}
}
return script;
}
and then, UserControls implementing IClientReferenceProvider can either return the ID of the main container control or even return a reference to a custom object that provides a client interface to parent objects like:MyUserControl.ascx
<script type="text/javascript">
<%= ClientID %> = {
show: function(activityID) {
<%= Store1.ClientID %>.baseParams.activityID = activityID;
<%= Store1.ClientID %>.load();
<%= Window1.ClientID %>.show();
}
};
</script>
MyUserControl.ascx.cspublic class MyUserControl : UserControl, IClientReferenceProvider
{
public string GetClientReference() {
return ClientID;
}
}
It's not 100% elegent but it's proved useful in UserControls that build heavily on existing controls with minimal additional logic. What do you think? Maybe I'm altogether missing a better way of doing this...?