<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://dotnetslackers.com/Community/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Brian Mains Blog</title><subtitle type="html">This blog will discuss features about .NET, both windows and web development.</subtitle><id>http://dotnetslackers.com/Community/blogs/bmains/atom.aspx</id><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/default.aspx" /><link rel="self" type="application/atom+xml" href="http://dotnetslackers.com/Community/blogs/bmains/atom.aspx" /><generator uri="http://communityserver.org" version="3.1.30415.43">Community Server</generator><updated>2008-07-16T06:56:00Z</updated><entry><title>Differences in AJAX Control Toolkit Controls and Extenders Client State</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/20/differences-in-ajax-control-toolkit-controls-and-extenders-client-state.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/20/differences-in-ajax-control-toolkit-controls-and-extenders-client-state.aspx</id><published>2008-08-20T19:59:00Z</published><updated>2008-08-20T19:59:00Z</updated><content type="html">&lt;p&gt;Sorry for the long title, but I wanted to post about some of the differences between the controls and extenders client component&amp;#39;s client state, which are defined for AjaxControlToolkit.ControlBase and AjaxControlToolkit.BehaviorBase on the client.&amp;nbsp; In developing an AJAX Control Toolkit control, I&amp;#39;ve come to find some of the differences.&amp;nbsp; One of the key differences is with client state.&lt;/p&gt;
&lt;p&gt;Client State is a hidden field mechanism that stores data about the current state of the AJAX control.&amp;nbsp; For an AJAX control toolkit extender that supports client state, on the client the get_ClientState and set_ClientState properties are avaialble to read/write data to this hidden variable.&amp;nbsp; This works really easily on the client, plus it allows the server to access the value through the ClientState property, and load/save the client state value.&lt;/p&gt;
&lt;p&gt;For a control, however, a control developer needs to override the SupportsClientState property, and return true.&amp;nbsp; Furthermore, there are no equivalent properties on the client.&amp;nbsp; Instead, the get_clientStateField and set_clientStateField get and set the reference to the field, so it&amp;#39;s possible to read and write the values using this reference through get_clientStateField().value.&amp;nbsp; This only works if SupportsClientState is set to true.&amp;nbsp; Controls also have to use the LoadClientState and SaveClientState methods to load/save state.&amp;nbsp; State is loaded whenever LostPostData occurs and saved when the hidden field is registered.&lt;/p&gt;
&lt;p&gt;Another interesting variation is that the control base class uses the ScriptManager&amp;#39;s RegisterHiddenField, whereas the extender creates its own hidden field reference so that the developer can work directly with the ClientState property.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28550" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>AJAX Errors: &lt;Namespace&gt; is undefined</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/20/ajax-errors-lt-namespace-gt-is-undefined.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/20/ajax-errors-lt-namespace-gt-is-undefined.aspx</id><published>2008-08-20T12:44:00Z</published><updated>2008-08-20T12:44:00Z</updated><content type="html">&lt;p&gt;One of the errors that frustrated me when developing AJAX controls was when I got &amp;lt;Namespace&amp;gt; is undefined, even though the script appeared to be correct.&amp;nbsp; I couldn&amp;#39;t figure it out right away because the class was registered correctly and the namespace was defined properly as well.&amp;nbsp; So what could be the issue?&lt;/p&gt;
&lt;p&gt;To help make AJAX development easier, I use a CodeSmith script to generate the shell AJAX component code, which works really well.&amp;nbsp; This time when I got the error, it was for a component I created manually without the script.&amp;nbsp; As soon as I replaced my code with the CodeSmith template generation code, the component began to work.&lt;/p&gt;
&lt;p&gt;What this means is that while sometimes the error may be a missing component reference (like the System.Web.Extensions assembly or the AJAX Control TOolkit dll), more often the issue could be an issue with the formatting of your script, like a missing comma or curly brace, something like that.&amp;nbsp; Something small that even VS wasn&amp;#39;t picking up with its limited error checking.&lt;/p&gt;
&lt;p&gt;So, a word of caution: write your script, and check it twice &lt;img src="http://dotnetslackers.com/Community/emoticons/emotion-2.gif" alt="Big Smile" /&gt;&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28547" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>TDD and Object Development</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/17/tdd-and-object-development.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/17/tdd-and-object-development.aspx</id><published>2008-08-16T20:00:00Z</published><updated>2008-08-16T20:00:00Z</updated><content type="html">&lt;p&gt;When using TDD practices, you may think ahead a little bit to a situation in the future.&amp;nbsp; For instance, suppose you have this:&lt;/p&gt;
&lt;p&gt;public class CustomerClassification&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; public CustomerClassification(string name, string type)&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Name = name;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Type = type;&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; public string Name&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _name; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { _name = value; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; public string Type&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _type; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { _type = value; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;It&amp;#39;s tempting to think that the property values will need to be change for some reason in the future, even though your current tests and current development of the application don&amp;#39;t identify a need for a setter.&amp;nbsp; I&amp;#39;d recommend that you leave out the setter until you actually see a need for adding it in.&amp;nbsp; The reason is that this is more inline with TDD (implement it only when you need it), plus setters may cause problems in the future (changing values that shouldn&amp;#39;t be changed as the constructor would be the only point of entry).&lt;/p&gt;
&lt;p&gt;A perspective in the light of TDD... this may not always be a valid reason and I&amp;#39;m definitely not against setters,but it&amp;#39;s something to consider.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28472" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="Testing/Test Tools" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/Testing_2F00_Test+Tools/default.aspx" /></entry><entry><title>AJAX $find Usefulness</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/11/ajax-find-usefulness.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/11/ajax-find-usefulness.aspx</id><published>2008-08-11T02:23:00Z</published><updated>2008-08-11T02:23:00Z</updated><content type="html">&lt;p&gt;Every AJAX control or extender you build has an ID on the client, accessible through get_id and set_id.&amp;nbsp; This ID is a unique ID and doesn&amp;#39;t have to match the ID of the control it&amp;#39;s given on the server, but the script registration process ensures that the server and client match.&amp;nbsp; So, using the ID, $find can reference the client component of any AJAX control on the page like so:&lt;/p&gt;
&lt;p&gt;&amp;lt;script language=&amp;quot;javascript&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;function pageLoad()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;var tabs = $find(&amp;quot;&amp;lt;%= tc.ClientID %&amp;gt;&amp;quot;);&lt;br /&gt;&amp;nbsp;//do something&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ajax:TabContainer ID=&amp;quot;tc&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;!-- Tab Panels --&amp;gt;&lt;br /&gt;&amp;lt;/ajax:TabContainer&amp;gt;&lt;/p&gt;
&lt;p&gt;The client component has a handy set of features, such as getting or setting the active tab index (through get_activeTabIndex and set_activeTabIndex) or polling the collection of tabs.&amp;nbsp; Each AJAX component has a client architecture you can take advantage of; it may take some getting used to that fact, but if you dig through the AJAX control toolkit code available on &lt;a href="http://www.codeplex.com"&gt;http://www.codeplex.com&lt;/a&gt;, you&amp;#39;ll learn more about what is available to you on the client.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28343" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>AJAX Properties in Description</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/11/ajax-properties-in-description.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/11/ajax-properties-in-description.aspx</id><published>2008-08-11T02:13:00Z</published><updated>2008-08-11T02:13:00Z</updated><content type="html">&lt;p&gt;I may have mentioned somewhere in my blog that AJAX components go through a process of describing the properties and events (at&amp;nbsp;least) so that the server component can push down values to the client.&amp;nbsp; This process happens in the GetScriptDescriptors method.&amp;nbsp; The ScriptDescriptor,which has three deriviatives, notes a component&amp;#39;s properties and events by using the following approach:&lt;/p&gt;
&lt;p&gt;ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor(&amp;quot;&amp;lt;full client class name&amp;gt;&amp;quot;, targetControl.ClientID);&lt;br /&gt;descriptor.AddProperty(&amp;quot;highlightCellOnMouseOver&amp;quot;, this.HighlightCellOnMouseOver);&lt;br /&gt;descriptor.AddProperty(&amp;quot;highlightRowOnMouseOver&amp;quot;, this.HighlightRowOnMouseOver);&lt;/p&gt;
&lt;p&gt;return new ScriptDescriptor[] { descriptor };&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Notice a few things: first off, the AJAX component I&amp;#39;m creating is a custom extender.&amp;nbsp; You can tell this because I used ScriptBehaviorDescriptor (I would have used ScriptControlDescriptor for an AJAX control).&amp;nbsp; The AddProperty method adds properties for the description process; in this way, the AddProperty method passes along a value established on the server to the client, to act as a default value of sorts.&lt;/p&gt;
&lt;p&gt;In reality, on the client side those properties have the following definition:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;get_highlightCellOnMouseOver : function()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;return this._highlightCellOnMouseOver;&lt;br /&gt;},&lt;/p&gt;
&lt;p&gt;set_highlightCellOnMouseOver : function(value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;if (this._highlightCellOnMouseOver != value)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;this._highlightCellOnMouseOver = value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;this.raisePropertyChanged(&amp;quot;highlightCellOnMouseOver&amp;quot;);&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;},&lt;/p&gt;
&lt;p&gt;get_highlightRowOnMouseOver : function()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;return this._highlightRowOnMouseOver;&lt;br /&gt;},&lt;/p&gt;
&lt;p&gt;set_highlightRowOnMouseOver : function(value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;if (this._highlightRowOnMouseOver != value)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;this._highlightRowOnMouseOver = value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;this.raisePropertyChanged(&amp;quot;highlightRowOnMouseOver&amp;quot;);&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;},&lt;/p&gt;
&lt;p&gt;So theoretically they can be changed during the client&amp;#39;s lifecycle, but at least a default value is established on the server.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28342" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>AutoCompleteExtender Client API</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/04/autocompleteextender-client-api.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/04/autocompleteextender-client-api.aspx</id><published>2008-08-04T02:12:00Z</published><updated>2008-08-04T02:12:00Z</updated><content type="html">&lt;p&gt;I previously posted about the format that a web service method has to be in for the AutoCompleteExtender to work.&amp;nbsp; This blog post focuses on some of the other capabilities of this extender.&amp;nbsp; In an example web method, I concatenate text and return the concatenation using LINQ as follows.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:small;"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;WebMethod&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;font size="3" color="#0000ff"&gt;
&lt;p&gt;public&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/span&gt;&lt;span style="font-size:small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;[] GetTopSearchPhrases(&lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; prefixText, &lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;int&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; count) {&lt;span style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;&amp;nbsp; SearchManager&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; manager = &lt;/span&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;SearchManager&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;.GetManager();&lt;span style="font-size:small;"&gt; &lt;span style="font-size:small;"&gt;&lt;font size="3"&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/span&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;&lt;span style="font-size:small;color:#2b91af;"&gt;&amp;nbsp; SearchPhraseCollection&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;phraseCollection = manager.GetTopSearchPhrases(prefixText, count);&lt;span style="font-size:small;"&gt; &lt;span style="font-size:small;"&gt;&lt;font size="3"&gt;
&lt;p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt; return&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; (&lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;from&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; p &lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;in&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;phraseCollection &lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;select&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; &lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;.Format(&lt;/span&gt;&lt;span style="font-size:small;color:#a31515;"&gt;&lt;span style="font-size:small;color:#a31515;"&gt;&amp;quot;{0} ({1} occurrence(s))&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;, p.Phrase, p.ResultCount.ToString())).ToArray();&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;What I want to do is get the results as:&lt;/p&gt;
&lt;p&gt;Microsoft .NET (21 occurence(s))&lt;br /&gt;Microscopes (122 occurence(s))&lt;/p&gt;
&lt;p&gt;And so on.&amp;nbsp; But, when the user selects an item in the list, I do not want the parenthesized text to appear in the textbox.&amp;nbsp; To trim this, I added a javascript event handler for the OnClientItemSelected event, that does this:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;color:#008000;"&gt;&lt;span style="font-size:small;color:#008000;"&gt;//Ensures that the parenthesized text isn&amp;#39;t passed on&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;font size="3" color="#0000ff"&gt;
&lt;p&gt;function &lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/span&gt;&lt;span style="font-size:small;"&gt;autoComplete_itemSelected(sender, e) {&lt;span style="font-size:small;"&gt; &lt;span style="font-size:small;"&gt;&lt;font size="3"&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&amp;nbsp;var&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; text = e.get_text();&lt;span style="font-size:small;"&gt; &lt;span style="font-size:small;"&gt;&lt;font size="3"&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; (text.indexOf(&lt;/span&gt;&lt;span style="font-size:small;color:#a31515;"&gt;&lt;span style="font-size:small;color:#a31515;"&gt;&amp;#39;(&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;) &amp;gt; 0) {&lt;span style="font-size:small;"&gt;
&lt;p&gt;&amp;nbsp; text = text.substring(0, text.indexOf(&lt;/p&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;color:#a31515;"&gt;&lt;span style="font-size:small;color:#a31515;"&gt;&amp;#39;(&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;));&lt;span style="font-size:small;"&gt; &lt;span style="font-size:small;"&gt;&lt;font size="3"&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt; if&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; (text != &lt;/span&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;null&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt;&amp;amp;&amp;amp; text.length &amp;gt; 0)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = text.trimEnd(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-size:small;"&gt;&lt;font size="3"&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&lt;span style="font-size:small;color:#0000ff;"&gt;&amp;nbsp;var&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:small;"&gt; targetElement = sender.get_element();&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;&lt;/span&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;targetElement.value = text;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;What this does is it gets the text of the item currently selected.&amp;nbsp; Then, if the text contains a parenthesis, it strips it out.&amp;nbsp; If the text happens to be not null, it&amp;#39;s trimmed (to remove the extra spacing from &amp;quot; (&amp;quot; in the text; I&amp;#39;d rather programmatically trim than do a -1 just in case I change the formatting of the output string later and forget to change the accompanying event handler.&lt;/p&gt;
&lt;p&gt;Lastly, the sender is the AutoCompleteExtender client class, and get_element() returns a reference to the target textbox.&amp;nbsp; The value is overridden (as the AutoCompleteExtender assigns the selected value to the textbox, but our event handler occurs after that assignment, wiping out any changes already performed).&lt;/p&gt;
&lt;p&gt;You may wonder where get_text() came from; the event argument is AutoCompleteItemEventArgs, which has a get_text(), get_value(), and get_item() properties.&amp;nbsp; The latter is information about the item itself, whereas the first two contain the information about the items in the list.&amp;nbsp; You wouldn&amp;#39;t know without the documentation what this event arg was.&amp;nbsp; I found this out by looking in the AJAX control toolkit code myself.&amp;nbsp; I could have put a debugger breakpoint in the code and figured it out that way as well.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28209" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>Developing AJAX Controls</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/03/developing-ajax-controls.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/03/developing-ajax-controls.aspx</id><published>2008-08-03T02:18:00Z</published><updated>2008-08-03T02:18:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;When developing AJAX-ified controls using the AJAX&amp;nbsp;framework from microsoft and the AJAX control toolkit, you have to rethink the control development approach a little bit.&amp;nbsp; After all, the key to making AJAX controls work is rendering code on the client-side, and being the AJAX uses managed scripts, the scripting process has to be well thought out. It&amp;#39;s not that overtly difficult to create custom controls, but it does usually require large amounts of code.&amp;nbsp; I start off my scripts from a script that I have for CodeSmith.&amp;nbsp; This script is really helpful in that regard.&lt;/p&gt;
&lt;p&gt;Although preparation is needed, a paradigm shift is also needed as well.&amp;nbsp; Before control developers spent time rendering logic in the server-side, writing out the HTML to the browser in the Render method.&amp;nbsp; Now, with ASP.NET AJAX, it&amp;#39;s beneficial to render that logic on the client-side instead.&amp;nbsp; This is because controls can take advantage of more features this way.&lt;/p&gt;
&lt;p&gt;For instance, take the CheckBoxList control.&amp;nbsp; How advantageous would it be to be able to dynamically add/remove items to the list?&amp;nbsp; However, the logic exists on the server side to create the interface, and I ran into a problem this way because the client code had to know what the server is rendering in order for it to take advantage.&lt;/p&gt;
&lt;p&gt;If all of the rendering was done on the client-side, this moves the logic to one place, which allows client-side refreshing of the interface (even rebinding from data streamed through a web service).&amp;nbsp; This really makes controls more advanced, but more cumbersome as client-side code becomes more verbose and difficult to manage.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28207" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>July 17th Presentation</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/03/july-17th-presentation.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/03/july-17th-presentation.aspx</id><published>2008-08-02T20:49:00Z</published><updated>2008-08-02T20:49:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;Although the presentation is already done, the powerpoint and code samples I used for a presentation on AJAX custom controls and extenders is available on the Central Penn&amp;#39;s .NET user group web site at: &lt;a href="http://www.central-penn.net"&gt;http://www.central-penn.net&lt;/a&gt; in the downloads section.&lt;/p&gt;
&lt;p&gt;The Central Penn .NET user group is a group for the central Pennsylvania that discusses anything .NET related.&amp;nbsp; They have some good speakers at their presentations, so if you get a chance, come on out the third Tuesday of the month.&amp;nbsp; You may catch me presenting again sometime in the future; I am planning on speaking for their Code Camp the first Saturday of December.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28206" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="Presentations" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/Presentations/default.aspx" /></entry><entry><title>AutoCompleteExtender Web Service</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/02/autocompleteextender-web-service.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/02/autocompleteextender-web-service.aspx</id><published>2008-08-02T01:17:00Z</published><updated>2008-08-02T01:17:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;If you&amp;#39;ve worked with the AutoCompleteExtender, you know that the extender returns a nice drop down list that only contains items with the keywords entered.&amp;nbsp; As you type more and more characters, the results in the list are filtered by the characters currently entered, until the item sought after is the only one left, or no items are left.&lt;/p&gt;
&lt;p&gt;Personally, I had a really hard time getting this to work, and what I didn&amp;#39;t realize is that the service requires a specific layout.&amp;nbsp; This layout should be in the form:&lt;/p&gt;
&lt;p&gt;[WebMethod]&lt;br /&gt;public string[] GetAutoCompleteResults(string prefixText, int count) { }&lt;/p&gt;
&lt;p&gt;or, if using a context key:&lt;/p&gt;
&lt;p&gt;[WebMethod]&lt;br /&gt;public string[] GetAutoCompleteResults(string prefixText, int count, string contextKey) { }&lt;/p&gt;
&lt;p&gt;Then the AutoCompleteExtender can hook up to the service and call this method, providing real-time filtered results.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28205" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>AJAX Web Services</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/01/ajax-web-services.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/08/01/ajax-web-services.aspx</id><published>2008-07-31T22:16:00Z</published><updated>2008-07-31T22:16:00Z</updated><content type="html">&lt;p&gt;Connecting to web services in AJAX is really easy.&amp;nbsp; To setup a web service that can be called on the client, simply do the following.&amp;nbsp; Create a web service in Visual Studio; add one to the web project by right-clicking on the desired folder and selecting the new item option.&amp;nbsp; Select the web service option, which creates an ASMX.&amp;nbsp; This is the extension for a service in the web project.&lt;/p&gt;
&lt;p&gt;Add the following attribute:&amp;nbsp; [System.Web.Scripts.Service.ScriptService]&amp;nbsp; When the project runs, a client proxy is generated automatically for you, one that matches your namespace/class name.&amp;nbsp; If you create a service in namespace Mains.Examples, with a service name of ArticleCodeGenerator, the following can be run on the client without having to write any code:&lt;/p&gt;
&lt;p&gt;&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function pageLoad()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mains.Examples.ArticleCodeGenerator.GenerateOutline(onSuccess, onFailure, $get(&amp;#39;&amp;lt;%= lblTemplate.ClientID %&amp;gt;&amp;#39;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function onSuccess(results, userContext, methodName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //called when successful call to service&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //results equals the&amp;nbsp;object returned from the service&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //userContext is the reference to the label&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function onFailure(results, userContext, methodName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //called when&amp;nbsp;failure&amp;nbsp;occurs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;asp:Label id=&amp;quot;lblTemplate&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;The way the service method is setup is illustrated in the following:&lt;/p&gt;
&lt;p&gt;ServiceMethod( &amp;lt;any parameters separated by commas&amp;gt;, &amp;lt;success callback&amp;gt;, &amp;lt;failed callback&amp;gt;, &amp;lt;context&amp;gt;);&lt;/p&gt;
&lt;p&gt;The success or failed callback has to meet the template shown above; results contains a reference to the object returned from the method.&amp;nbsp; If an actual object and not a primitive type, the object is converted using JSON.&amp;nbsp; The context object can in reality be anything, and is often passed a value to the UI control (as shown in many examples).&lt;/p&gt;
&lt;p&gt;Add a reference to the service to the script manager:&lt;/p&gt;
&lt;p&gt;&amp;lt;asp:ScriptManager ...&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;Services&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:ScriptReference Path=&amp;quot;..path to ASMX&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Services&amp;gt;&lt;br /&gt;&amp;lt;/asp:ScriptManager&amp;gt;&lt;/p&gt;
&lt;p&gt;That&amp;#39;s how easy it is to include&amp;nbsp;web services into AJAX.&amp;nbsp; Even cooler is how Visual Studio provides intellisense for this object.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=28191" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>AJAX: Working with Events</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/ajax-working-with-events.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/ajax-working-with-events.aspx</id><published>2008-07-17T18:14:00Z</published><updated>2008-07-17T18:14:00Z</updated><content type="html">&lt;p&gt;Events in ASP.NET AJAX are quite unlike the events in the .NET framework.&amp;nbsp; Rather than having explicit events and event handlers, the framework provides a workaround to this approach that doesn&amp;#39;t require any&amp;nbsp;custom syntax definitions&amp;nbsp;to JavaScript itself, while still being able to expose the capability.&lt;/p&gt;
&lt;p&gt;The approach is to expose events using an events property.&amp;nbsp; This events property is defined in the Sys.Component class, the base class of all controls and extenders.&amp;nbsp; The get_events() property setter&amp;nbsp;returns an object of type EventHandlerList.&amp;nbsp; This object can add event references to client events stored in a key.&amp;nbsp; For instance, the following methods add, remove, and raise an event.&amp;nbsp; These methods are located in the prototype definition, which is why the function declaration is at the end.&lt;/p&gt;
&lt;p&gt;add_propertyChanged : function(handler) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.get_events().addHandler(&amp;quot;propertyChanged&amp;quot;, handler);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;remove_propertyChanged : function(handler) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.get_events().removeHandler(&amp;quot;propertyChanged&amp;quot;, handler);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;raise_propertyChanged : function()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var handler = this.get_events().getHandler(&amp;quot;propertyChanged&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (handler != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; handler(this, Sys.EventArgs.Empty);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;Working with events are done by methods that map the name of the event to a handler.&amp;nbsp; The event is referenced by a string that uniquely identifies the event.&amp;nbsp; Any clients registering to this event would register the name of a JavaScript method.&amp;nbsp; This JavaScript method would be the event handler for the event in the ASPX page that the control or extender resides in.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s up to something in the AJAX control or extender to call raise_propertyChanged.&amp;nbsp; When some member does (property or method), this then triggers the propertyChanged event.&amp;nbsp; An event handler in the ASPX would receive notification of it, and would be passed the sender and event argument (though the method doesn&amp;#39;t have to accept these parameters).&amp;nbsp; An event handler can be wired up like so:&lt;/p&gt;
&lt;p&gt;&amp;lt;script language=&amp;quot;JavaScript&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function propertyChangedHandler(sender, e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert(&amp;quot;prop changed&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var ctl = $find(&amp;#39;&amp;lt;%= MyControl.ClientID %&amp;gt;&amp;#39;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctl.add_propertyChanged(propertyChangedHandler);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p&gt;Anything that triggers this event will call the propertyChangedHandler JavaScript method.&amp;nbsp; This method is a client-side event handler for our purpose.&amp;nbsp; Something in the component actually needs to call raise_propertyChanged() to fire the event, but our event handler will catch it.&lt;/p&gt;
&lt;p&gt;In ASP.NET AJAX components, the typical way to expose events is through a property (as oxy moronic as that may be).&amp;nbsp; The property stores the name of the JavaScript event handler (propertyChangedHandler) and passes it to the client script when the component is described.&amp;nbsp; In an ASP.NET AJAX component, this is done using GetScriptDescriptors, with&amp;nbsp;a statement as shown below:&lt;/p&gt;
&lt;p&gt;descriptor.AddEvent(&amp;quot;propertyChanged&amp;quot;, this.OnClientPropertyChanged);&lt;/p&gt;
&lt;p&gt;It&amp;#39;s by convention to include &amp;quot;OnClient&amp;quot; for event handlers to a client event.&amp;nbsp; Using the AJAX Control Toolkit approach, events can be declared using the following approach:&lt;/p&gt;
&lt;p&gt;[&lt;br /&gt;ExtenderControlEvent,&lt;br /&gt;ClientPropertyName(&amp;quot;propertyChanged&amp;quot;)&lt;br /&gt;]&lt;br /&gt;public string OnClientPropertyChanged&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { .. }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { .. }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;At runtime, the AJAX component is dynamically described by using the metadata defined in the attributes of the property definition, which it sees that the OnClientPropertyChanged property contains the name of a method that is an event handler.&amp;nbsp; This event handler is passed to the add_propertyChanged method.&amp;nbsp; When that event is raised, the event handler defined here gets fired.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=27908" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>AJAX: Working with Properties</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/ajax-working-with-properties.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/ajax-working-with-properties.aspx</id><published>2008-07-17T16:00:00Z</published><updated>2008-07-17T16:00:00Z</updated><content type="html">&lt;p&gt;In JavaScript, there really isn&amp;#39;t such as thing as properties.&amp;nbsp; Essentially a read/write property is represented by two methods, one with a &amp;quot;get_&amp;quot; prefix and one with a &amp;quot;set_&amp;quot; prefix.&amp;nbsp; However, the ASP.NET AJAX framework separates this as just a method; for instance, the following property definition is shown below:&lt;/p&gt;
&lt;p&gt;//note the function declaration after is the prototype syntax, as properties are note&lt;br /&gt;get_text : function()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; return this._text;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;set_text : function(value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; if (this._text != value)&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this._text&amp;nbsp;= value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.raisePropertyChanged(&amp;quot;text&amp;quot;);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;In javascript, you can&amp;#39;t reference the property via &amp;quot;text&amp;quot; and work with it like a property in .NET.&amp;nbsp; You have to use the get_text() and set_text(&amp;quot;text&amp;quot;) method calls; however, in .NET, you can work with it like a &amp;quot;text&amp;quot; property when you describe it.&amp;nbsp; Every ASP.NET AJAX server control needs to describe its client counterpart in the GetScriptDescriptors method; to describe a property can simply be done by:&lt;/p&gt;
&lt;p&gt;descriptor.AddProperty(&amp;quot;text&amp;quot;, this.Text);&lt;/p&gt;
&lt;p&gt;Notice the property doesn&amp;#39;t need to specify &amp;quot;get_&amp;quot; or &amp;quot;set_&amp;quot; at all; it can simply reference it as &amp;quot;text&amp;quot; (the framework appends a &amp;quot;get_&amp;quot; or &amp;quot;set_&amp;quot; when it makes the actual assignment.&amp;nbsp; Also, the second parameter of AddProperty pushes down the current value of Text stored on the server-side, which acts as the initial value at load time.&lt;/p&gt;
&lt;p&gt;If you use the AJAX Control Toolkit approach to developing custom controls or extenders you don&amp;#39;t need to define GetScriptDescriptors; rather, the framework does it for you using reflection of attributes, shown below:&lt;/p&gt;
&lt;p&gt;[&lt;br /&gt;ExtenderControlProperty,&lt;br /&gt;ClientScriptResource(&amp;quot;text&amp;quot;)&lt;br /&gt;]&lt;br /&gt;public string Text { .. }&lt;/p&gt;
&lt;p&gt;ExtenderControlProperty notes that Text should be described as a property, while ClientScriptResources states what the property is named.&amp;nbsp; You don&amp;#39;t need to use ClientScriptResource if the server-side property name matches the client side name, but the matching is case sensitive and our script uses lower camel case instead of upper as on the server, which is why I defiend the attribute.&amp;nbsp; At runtime, the previous descriptor.AddProperty statement is created automatically for us and the script is described correctly.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=27907" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>AJAX Control Toolkit's ComponentReferenceAttribute and ElementReferenceAttribute</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/ajax-control-toolkit-s-componentreferenceattribute-and-elementreferenceattribute.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/ajax-control-toolkit-s-componentreferenceattribute-and-elementreferenceattribute.aspx</id><published>2008-07-17T13:25:00Z</published><updated>2008-07-17T13:25:00Z</updated><content type="html">&lt;p&gt;If you&amp;#39;ve done custom development using the AJAX Control Toolkit, you know that the approach the framework takes is an attribute-based approach.&amp;nbsp; If you haven&amp;#39;t looked at this before, check out this brief example (there are some other sections on the site that are helpful): &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Walkthrough/CreatingNewExtender.aspx"&gt;http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Walkthrough/CreatingNewExtender.aspx&lt;/a&gt;.&amp;nbsp; There are som explanations of the attributes that can be used here:&amp;nbsp; &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Walkthrough/ExtenderClasses.aspx"&gt;http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Walkthrough/ExtenderClasses.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The ComponentReference is a very useful attribute, which I didn&amp;#39;t see in the links above.&amp;nbsp; This attribute can be used on a property that holds the ID of a control.&amp;nbsp; It will internally find the control reference and provide a reference to the AJAX class for that control.&amp;nbsp; Let&amp;#39;s assume the following property as an example:&lt;/p&gt;
&lt;p&gt;public string AjaxControlID { .. }&lt;/p&gt;
&lt;p&gt;The AjaxControlID property stores the ID of a control that emits an AJAX script.&amp;nbsp; An AJAX control has both a server-side component and a client-side component.&amp;nbsp; For instance, the TabContainer control has an AjaxControlToolkit.TabContainer server component and an AjaxControlToolkit.TabContainer client component.&amp;nbsp; ComponentReference is a shortcut way, by using the ID, to gain reference to the client component (thie client component has a get_id getter that has the same ID as the control.&lt;/p&gt;
&lt;p&gt;While ComponentReference gets a reference to the client component, ElementReference gets a reference to the HTML element that the client component extends.&amp;nbsp; Every AJAX control and extender works with some underlying HTML element; an extender&amp;nbsp;targets a different HTML element with its javascript, while a control renders its own interface, which means it extends the HTML element it renders.&lt;/p&gt;
&lt;p&gt;So if we have a server property:&lt;/p&gt;
&lt;p&gt;[&lt;br /&gt;ExtenderControlProperty,&lt;br /&gt;ClientScriptResource(&amp;quot;extenderControl&amp;quot;),&lt;br /&gt;ComponentProperty&lt;br /&gt;]&lt;br /&gt;public string ExtenderControlID&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { .. }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { .. }&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;Which maps to the client class&amp;#39;s property getter/setter defined in the prototype definition:&lt;/p&gt;
&lt;p&gt;get_extenderControl : function()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; return this._extenderControl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;set_extenderControl&amp;nbsp;: function(value)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; this._extenderControl = value;&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;The reference to the component for the extender is accessible on the client side; _extenderControl references the custom AJAX class for the extender.&amp;nbsp; If the property used ElementReference, it would reference the HTML element that the extender represents.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=27906" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry><entry><title>LINQ to SQL and Data Context Awareness</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/linq-to-sql-and-data-context-awareness.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/17/linq-to-sql-and-data-context-awareness.aspx</id><published>2008-07-17T12:56:00Z</published><updated>2008-07-17T12:56:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;If you have developed applications with LINQ to SQL, you know that one of the features of these objects are that they are aware of the DataContext they were created in.&amp;nbsp; This can have issues in ASP.NET if you do not cache the DataContext it belonged to, because each LINQ to SQL business object knows which context it was created in, and if it isn&amp;#39;t the current one, then an exception is thrown.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s possible to create new business objects without them being known by the DataContext; when you first create an object, until that object is passed along to the DataContext through InsertOnSubmit, the data object can be a temporary holder of data disconnected from the database.&amp;nbsp; It&amp;#39;s also possible to create relationships for the data that are also disconnected from the database, so you can build a whole tree of relationships of objects rather easily, all in disconnected form.&lt;/p&gt;
&lt;p&gt;If you like to use that approach, use caution.&amp;nbsp; If you add one object as a reference to a disconnected object that is DataContext-aware, then all of the other disconnected objects related to that object will all be queued up for insertion, which is a HUGE pain.&amp;nbsp; If you get a lot of duplicated data, this is the first place to look; is a DataContext-aware object reference being assigned anywhere?&amp;nbsp; If so, remove it, and make a reference by key.&lt;/p&gt;
&lt;p&gt;That can pose problems because one of the nice features of LINQ to SQL is being able to drill-down an object model using the PK/FK properties, but in disconnected mode, all of the data has to be disconnected, and reference data won&amp;#39;t work because you aren&amp;#39;t usually creating it on the fly.&amp;nbsp; Creating temporary matching records isn&amp;#39;t typically a good idea as well, because if they aren&amp;#39;t removed, data will be duplicated, plus removing the objects later may damage the reference for the real value potentially.&lt;/p&gt;
&lt;p&gt;So what are the options here?&amp;nbsp; I&amp;#39;d recommend storing as little disconnected data as posslble, or make sure you tread lightly.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=27904" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="LINQ" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/LINQ/default.aspx" /></entry><entry><title>AJAX Descriptors</title><link rel="alternate" type="text/html" href="http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/16/ajax-descriptors.aspx" /><id>http://dotnetslackers.com/Community/blogs/bmains/archive/2008/07/16/ajax-descriptors.aspx</id><published>2008-07-16T02:56:00Z</published><updated>2008-07-16T02:56:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;So what is the purpose of the descriptor?&amp;nbsp; The descriptor describes information about the component, such as properties, events, and methods.&amp;nbsp; For properties, the descriptor states the name and type of the property, as well as whether the property is read-only or if null values are allowed.&lt;/p&gt;
&lt;p&gt;So what does that govern?&amp;nbsp; I was changing a component and found out that it governs a lot because whenever I changed the definition of the property, an exception was thrown at runtime, stating that a readonly property had a setter definition.&amp;nbsp; So the ASP.NET AJAX framework is aware about your structures through the descriptor, and does perform validation.&lt;/p&gt;&lt;img src="http://dotnetslackers.com/Community/aggbug.aspx?PostID=27839" width="1" height="1"&gt;</content><author><name>bmains</name><uri>http://dotnetslackers.com/Community/members/bmains.aspx</uri></author><category term="AJAX" scheme="http://dotnetslackers.com/Community/blogs/bmains/archive/tags/AJAX/default.aspx" /></entry></feed>