<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.componentart.com/BLOGS/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>The Blog of Milos</title><link>http://www.componentart.com/BLOGS/milos/default.aspx</link><description>Web.UI news and more</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Debug Build: 61019.2)</generator><item><title>AZGroups Scott Guthrie Event 2009, Phoenix</title><link>http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx</link><pubDate>Tue, 02 Jun 2009 15:31:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:31036</guid><dc:creator>Milos</dc:creator><slash:comments>1</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/31036.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=31036</wfw:commentRss><description>&lt;p&gt;Last week I had the pleasure of attending the annual &lt;a href="http://azgroups.org/"&gt;AZGroups&lt;/a&gt; event in Phoenix, Arizona headlined by Scott Guthrie of Microsoft. Other speakers included Tim Heuer, Jaime Rodriguez (on WPF) and Glenn Block (on MEF). All the sessions were very informative and the event overall was extremely well organized.&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;I had a great time in Scottsdale and even got to participate in the goings on by presenting our new &lt;a href="http://www.componentart.com/products/soaui/"&gt;SOA.UI framework&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;img src="http://blogs.componentart.com/milos/images/phoenix2.jpg" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;img src="http://blogs.componentart.com/milos/images/phoenix1.jpg" /&gt;&lt;br /&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;You can see the rest of the pics from the event &lt;a href="http://www.flickr.com/photos/scottcate/sets/72157619036373689/"&gt;here&lt;/a&gt;.&lt;/p&gt;
A big thanks to Scott Cate, Joseph Guadagno, and the rest of the organizers!
&lt;br /&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx&amp;amp;;subject=AZGroups+Scott+Guthrie+Event+2009%2c+Phoenix" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx&amp;amp;;title=AZGroups+Scott+Guthrie+Event+2009%2c+Phoenix" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx&amp;amp;title=AZGroups+Scott+Guthrie+Event+2009%2c+Phoenix" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/06/02/scott-guthrie-event-2009-phoenix-az.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=31036" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/silverlight/default.aspx">silverlight</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/soa.ui/default.aspx">soa.ui</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/phoenix/default.aspx">phoenix</category></item><item><title>Securing Applications Built on Silverlight and WCF</title><link>http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx</link><pubDate>Thu, 07 May 2009 14:41:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:29917</guid><dc:creator>Milos</dc:creator><slash:comments>1</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/29917.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=29917</wfw:commentRss><description>&lt;br /&gt;
Having recently released our initial offering of Silverlight controls, we are starting to get a feel for the sorts of issues Silverlight
developers commonly encounter in designing and developing their applications. One question which seems to pop up frequently is how
security and authentication should be handled in the context of a Silverlight application which interacts with WCF services. In applications
that include &lt;a href="http://www.componentart.com/products/silverlight/"&gt;Web.UI controls&lt;/a&gt;, especially those 
with &lt;a href="http://www.componentart.com/products/soaui/"&gt;SOA.UI integration&lt;/a&gt;, this question becomes even more important.
&lt;br /&gt;
&lt;br /&gt;
In this post, I will attempt to shine a bit of light on what we see as a typical approach to authentication and how it can be elegantly
integrated into a Silverlight 2 application and the WCF services it employs. We will use the example of simple ASP.NET forms authentication.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Step 1.&lt;/strong&gt; Configure authentication for the application in its web.config file:
&lt;br /&gt;
&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;&amp;lt;system.web&amp;gt;
  ...
  &amp;lt;authentication mode=&amp;quot;Forms&amp;quot;&amp;gt;
    &amp;lt;forms name=&amp;quot;secure&amp;quot;&amp;gt;
      &amp;lt;credentials passwordFormat=&amp;quot;Clear&amp;quot;&amp;gt;
        &amp;lt;user name=&amp;quot;milos&amp;quot; password=&amp;quot;secret&amp;quot; /&amp;gt;
      &amp;lt;/credentials&amp;gt;
    &amp;lt;/forms&amp;gt;
  &amp;lt;/authentication&amp;gt;
  ...
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;

This is all we need to do to be able to rely on ASP.NET and its session cookies for authentication and session management. We do still need
to do a couple of things in order to connect our Silverlight and web service logic to this underlying mechanism.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Step 2.&lt;/strong&gt; Write a simple WCF authentication service:
&lt;br /&gt;
&lt;br /&gt;


&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;[ServiceContract(Namespace = &amp;quot;&amp;quot;)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AuthenticationService
{
  [OperationContract]
  public bool Authenticate(string sUser, string sPass)
  {
    if (FormsAuthentication.Authenticate(sUser, sPass))
    {
      FormsAuthentication.SetAuthCookie(sUser, false);
      return true;
    }

    return false;
  }

  [OperationContract]
  public bool IsAuthenticated()
  {
    return HttpContext.Current.User.Identity.IsAuthenticated;
  }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
In this example, we implement two methods: one for checking whether the user is authenticated and another for authenticating her. We rely
entirely on built-in FormsAuthentication functionality.
&lt;br /&gt;
&lt;br /&gt;
With the AuthenticationService in place, we can plug it into our Silverlight application and its associated WCF services (including standard
SOA.UI services). For the former, we can create a service reference in the Silverlight application and use it in this sort of way:

&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Step 3.&lt;/strong&gt; Implement authentication logic in the Silverlight application:
&lt;br /&gt;
&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;public partial class Page : UserControl
{
  public Page()
  {
    InitializeComponent();

    // When the page initializes, perform authentication if necessary:
    AuthenticateAndInitialize();
  }

  void AuthenticateAndInitialize()
  {
    // Check whether the user is authenticated:
    AuthenticationService.AuthenticationServiceClient oAuthClient = 
      new AuthenticationService.AuthenticationServiceClient(...);
    oAuthClient.IsAuthenticatedCompleted += 
      new EventHandler(oAuthClient_IsAuthenticatedCompleted);
    oAuthClient.IsAuthenticatedAsync();
  }

  void oAuthClient_IsAuthenticatedCompleted(object sender, 
    AuthenticationService.IsAuthenticatedCompletedEventArgs e)
  {
    if (e.Result)
    {
      // The user is already authenticated, proceed with initializing the application:
      InitializeApplication();
    }
    else
    {
      // Show login screen, get username and password (code not shown here), and authenticate:
      Authenticate(sUsername, sPassword);
    }
  }

  void Authenticate(string sUser, string sPass)
  {
    // Attempt to authenticate the given credentials:
    AuthenticationService.AuthenticationServiceClient oAuthClient = 
      new AuthenticationService.AuthenticationServiceClient(...);
    oAuthClient.AuthenticateCompleted += 
      new EventHandler(oAuthClient_AuthenticateCompleted);
    oAuthClient.AuthenticateAsync(sUser, sPass);
  }

  void oAuthClient_AuthenticateCompleted(object sender, 
    AuthenticationService.AuthenticateCompletedEventArgs e)
  {
    if (e.Result)
    {
      // The user is now authenticated, proceed with initializing the application:
      InitializeApplication();
    }
    else
    {
      // Login failed, repeat the login screen procedure (code not shown here).
    }
  }

  ...
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The (pseudo-)code above outlines the general approach to a simple login procedure which can be integrated into any Silverlight application.
We need to interface into this procedure from Silverlight because that is our client-side platform, but the authentication is actually
needed not for the client-side Silverlight operations, but for the server-side WCF layer. This brings us to the last step, and the real point
of the whole exercise: securing the service.
&lt;br /&gt;
&lt;br /&gt;

&lt;strong&gt;Step 4.&lt;/strong&gt; Secure the service:
&lt;br /&gt;
&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SoaFeedReaderDataGridService : SoaDataGridService
{
  public override SoaDataGridSelectResponse Select(SoaDataGridSelectRequest request)
  {
    &lt;strong&gt;if (HttpContext.Current.User.Identity.IsAuthenticated)&lt;/strong&gt;
    {
      // Implement service logic
      ...
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The idea is to have the service check the user&amp;#39;s credentials before proceeding to fetch data or perform other potentially sensitive
operations. In the example above, we are using a standard SOA.UI SoaDataGridService, but the same approach is used for any WCF service.

&lt;br /&gt;
&lt;br /&gt;
I hope this basic example clarifies things a bit when it comes to security and Silverlight+WCF applications. For more elaborate authentication
mechanisms, other options also exist, such as the ability to pass around custom data using SOA.UI APIs, but that is a topic for another day.
&lt;br /&gt;
&lt;br /&gt;
Cheers!
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx&amp;amp;;subject=Securing+Applications+Built+on+Silverlight+and+WCF" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx&amp;amp;;title=Securing+Applications+Built+on+Silverlight+and+WCF" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx&amp;amp;title=Securing+Applications+Built+on+Silverlight+and+WCF" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2009/05/07/securing-applications-built-on-silverlight-and-wcf.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=29917" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/web+services/default.aspx">web services</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/silverlight/default.aspx">silverlight</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/soa.ui/default.aspx">soa.ui</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/wcf/default.aspx">wcf</category></item><item><title>ComponentArt Silverlight Preview</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx</link><pubDate>Fri, 05 Dec 2008 17:15:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:25808</guid><dc:creator>Milos</dc:creator><slash:comments>3</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/25808.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=25808</wfw:commentRss><description>
&lt;p&gt;If you are wondering what we here at ComponentArt have been up to in the last while, wonder no more: we have been busily working on a foray into the world of Silverlight. It&amp;#39;a always exciting to play with a new user interface technology, not least one that is as well thought-out and powerful as this. We have put together a small but ever-growing demo application to showcase some of our archievements so far, which you can check out at &lt;a href="http://silverlight.componentart.com"&gt;silverlight.componentart.com.&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;I personally have been working on the &lt;a href="http://silverlight.componentart.com/#DataGrid"&gt;DataGrid&lt;/a&gt; control. Our aim with DataGrid, as with the rest of the suite, is to make controls which will retain all the familiar features and UI capabilities of our AJAX suite and include new ones which will utilize the best of what Silverlight brings to the game. &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Let us know what you think and what you would like to see in the upcoming ComponentArt Silverlight product line.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx&amp;amp;;subject=ComponentArt+Silverlight+Preview" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx&amp;amp;;title=ComponentArt+Silverlight+Preview" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx&amp;amp;title=ComponentArt+Silverlight+Preview" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/12/05/componentart-silverlight-preview.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=25808" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/datagrid/default.aspx">datagrid</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/silverlight/default.aspx">silverlight</category></item><item><title>Web.UI 2008.2 Grid News: Grouping</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx</link><pubDate>Tue, 23 Sep 2008 18:34:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:23733</guid><dc:creator>Milos</dc:creator><slash:comments>1</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/23733.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=23733</wfw:commentRss><description>&lt;br /&gt;

Now that Web.UI 2008.2 is officially out the door, I can take some time to sit back and reflect on what&amp;#39;s been done. There are some great new controls, as usual, and major enhancements to our Grid control. 
&lt;br /&gt;
&lt;br /&gt;

I&amp;#39;m particularly excited about that last part, as I&amp;#39;ve felt for a long time that some of the limitations with its grouping functionality needed to be addressed. With this release, we took the time to really re-think this aspect of the control, and instead of merely patching on additional features, to remake it in a powerful and elegant way and still keep it backward compatible. I believe we&amp;#39;ve managed to do that.
&lt;br /&gt;
&lt;br /&gt;

So, without further ado, here&amp;#39;s what&amp;#39;s new with Grid grouping:
&lt;br /&gt;
&lt;br /&gt;

&lt;strong&gt;Multiple Grouping&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;

One of the Grid&amp;#39;s major deficiencies for some time has been its inability to group by more than one column at a time. This had to do with various factors having to do mostly with the way we were rendering groups on the client. We have now surmounted those obstacles and groupings can be done on as many columns at a time as the user deems reasonable.
&lt;br /&gt;
&lt;br /&gt;

This ability extends across all running modes, usage scenarios and grouping modes.
&lt;br /&gt;
&lt;br /&gt;

Wait... Grouping modes?
&lt;br /&gt;
&lt;br /&gt;

&lt;strong&gt;Grouping Modes&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;

When re-thinking the way grouping should work in Grid, we realized that there are at least three different ways in which paging through a grouped record set could work:
&lt;br /&gt;
&lt;br /&gt;

ConstantRecords; in this mode, the number of actual data records, regardless of how many groups they are distributed across, remains constant across pages. This mode is very simple to handle programmatically, since data-access code doesn&amp;#39;t actually need to know anything about groupings. It simply retrieves the one page of records, which are then organized in appropriate groupings before being rendered on the client.
&lt;br /&gt;
&lt;br /&gt;

See demo here: &lt;a href="http://www.componentart.com/webui/demos/demos_control-specific/grid/sorting_and_grouping/grouping_constantRecords/default.aspx"&gt;ConstantRecords Grouping Mode&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;

Thanks to its simplicity, this grouping mode is supported in all running modes, including WebService.
&lt;br /&gt;
&lt;br /&gt;

ConstantGroups; this mode replicates the default grouping behaviour that Grid exhibited up to this point. Paging a Grid grouped in this mode means that the same number of top-level groups is present on every page. All the contents of those groups (sub-groups and records) are pre-loaded and no additional data access is required to expand and render that content.
&lt;br /&gt;
&lt;br /&gt;

See demo here: &lt;a href="http://www.componentart.com/webui/demos/demos_control-specific/grid/sorting_and_grouping/grouping_constantGroups/default.aspx"&gt;ConstantGroups Grouping Mode&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;

ConstantRows; the two modes described above have one common downside: as groups are expanded on the client, the number of rendered rows increases, and can stretch the height of the Grid control. With ConstantRows, the total number of rendered rows (records + group headings) is kept at the constant number dictated by GroupingPageSize.
&lt;br /&gt;
&lt;br /&gt;

See demo here: &lt;a href="http://www.componentart.com/webui/demos/demos_control-specific/grid/sorting_and_grouping/grouping_manual/default.aspx"&gt;ConstantRows Grouping Mode&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;

This running mode, when used in Server or Callback mode, requires some new server-side events (NeedGroups and NeedGroupData) to be handled in order to facilitate the efficient retrieval of only the necessary groups and records. 
&lt;br /&gt;
&lt;br /&gt;

Which brings us to our next topic...
&lt;br /&gt;
&lt;br /&gt;

&lt;strong&gt;Grouping + Manual Paging&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;

Up until this point, there was no good way to use manual paging (manual retrieval of just the required records from the database for each page) in conjunction with grouping with ComponentArt Grid. With the ConstantRecords and ConstantRows grouping modes, that is no longer a problem. Grouping can now be done while maintaining the efficiency of manual data retrieval.
&lt;br /&gt;
&lt;br /&gt;

&lt;strong&gt;Grouping + Scrolling&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;

The ConstantRows grouping mode provides an additional important benefit. To support grouping in conjunction with the Grid scroller, maintaining a constant number of rendered rows was crucial. A Grid which changes its height as it is scrolled completely ruins the visual feel of a scrolling interface. With ConstantRows, grouping can finally be used with the scroller.
&lt;br /&gt;
&lt;br /&gt;

See a demo here: 
&lt;a href="http://www.componentart.com/webui/demos/demos_control-specific/grid/sorting_and_grouping/grouping_scroll_callback/WebForm1.aspx"&gt;Scrolling a Grouped Grid in Callback Mode&lt;/a&gt;&lt;br /&gt;
And here: 
&lt;a href="http://www.componentart.com/webui/demos/demos_control-specific/grid/sorting_and_grouping/grouping_scroll_client/WebForm1.aspx"&gt;Scrolling a Grouped Grid in Client Mode&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;

&lt;strong&gt;Grouping + Web Services&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;

Grid&amp;#39;s WebService running mode, while offering the best possible performance and elegance of design, does have limitations due its inability to perform complex server-side logic as data is loaded. This makes it difficult to support the loading of groups on the server (web service), but once again, the grouping modes greatly improve the situation.
&lt;br /&gt;
&lt;br /&gt;

The ConstantRecords grouping mode is easily supported in WebService running mode, since it only relies on the regular paging of records. Through this mode, grouping is now supported with web services. In the future, we will be expanding this functionality to support as much of the other two grouping modes as we can, but we feel that this is already a decent start.
&lt;br /&gt;
&lt;br /&gt;

See a demo here: &lt;a href="http://www.componentart.com/webui/demos/demos_technology-showcase/web-services_ajax/grid_webServiceRunningMode/default.aspx"&gt;WebService Running Mode&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;

&lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;

We hope you find Grid&amp;#39;s new grouping functionality useful. We will continue to improve it and, as always, take your views and needs into account. Do let us know what you think.
&lt;br /&gt;
&lt;br /&gt;

Enhanced grouping isn&amp;#39;t the only thing that&amp;#39;s new in Grid 2008.2, but it&amp;#39;s certainly the most significant. Nevertheless, I will be writing about the other Grid enhancements in a follow-up post. Stay tuned.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx&amp;amp;;subject=Web.UI+2008.2+Grid+News%3a+Grouping" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx&amp;amp;;title=Web.UI+2008.2+Grid+News%3a+Grouping" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx&amp;amp;title=Web.UI+2008.2+Grid+News%3a+Grouping" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/09/23/web-ui-2008-2-grid-news-grouping.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=23733" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Grid/default.aspx">Grid</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/2008.2/default.aspx">2008.2</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Grouping/default.aspx">Grouping</category></item><item><title>Grid Configuration via Web Service</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx</link><pubDate>Fri, 13 Jun 2008 13:35:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:19796</guid><dc:creator>Milos</dc:creator><slash:comments>4</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/19796.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=19796</wfw:commentRss><description>&lt;br /&gt;
Since the introduction of the WebService running mode in ComponentArt Grid, and related functionality (like the client-side load method), we have seen this approach rapidly gain popularity and, naturally, produce demands for more features and more versatility.
&lt;br /&gt;
&lt;br /&gt;
Versatility is key when it comes to UI controls, so we have been spending some time improving WebService mode in this respect. As of Web.UI 2008.2 SP2 (build 2008.2.1180) Grid has a number of new features.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;WebServiceConfigMethod&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to being able to define ASP.NET AJAX web service methods for data selection, insertion, deletion, etc, it is now also possible to perform Grid configuration in a web service.
&lt;br /&gt;
&lt;br /&gt;
Rather than defining top-level properties, &lt;em&gt;GridLevels&lt;/em&gt; and their constituent &lt;em&gt;GridColumns&lt;/em&gt; and all the accompanying styles on the ASPX page where the Grid instance is placed, all of these can now be loaded on the fly by defining the &lt;em&gt;WebServiceConfigMethod&lt;/em&gt; server-side property and calling the client-side &lt;em&gt;webServiceConfig&lt;/em&gt; method.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;GridWebServiceConfigResponse&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
The web service method performing Grid configuration is expected to return an object of the type &lt;em&gt;GridWebServiceConfigResponse&lt;/em&gt;. Such an object contains top-level property settings (contained in the &lt;em&gt;Properties&lt;/em&gt; member), and &lt;em&gt;GridLevel&lt;/em&gt; definitions (contained in the Levels property) which, in turn, can contain &lt;em&gt;GridColumns&lt;/em&gt;.
&lt;br /&gt;
&lt;br /&gt;
Configuration can be done at any time on the client, without going back to the server from which the ASPX file originated. The configuration request passes in an optional custom parameter, so that configuration can be context-dependent. 
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;GridWebServiceSelectRequest.Columns&lt;/strong&gt; 
&lt;br /&gt;
&lt;br /&gt;
To enable such potential on-the-fly changes to the Grid&amp;rsquo;s layout and definition, &lt;em&gt;GridWebServiceSelectRequest&lt;/em&gt; now contains a &lt;em&gt;Columns&lt;/em&gt; property. With every web service data request, Grid now sends along the collection of columns (data fields) that it expects on the client. This allows the web service selection logic to account for on-the-fly changes in the Grid&amp;rsquo;s client-side configuration, and always provide the required data.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;And More&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to the above, a number of other enhancements to web service functionality have been made which should simplify its use in many scenarios and enable altogether new ones.
&lt;br /&gt;
&lt;br /&gt;
For example, &lt;em&gt;GridWebServiceSelectResponse.Items&lt;/em&gt; can now contain simple arrays of objects corresponding to the rows of data requested by the Grid. Simple proxy classes no longer need to be defined, as long as the order of data in the arrays matches the fields specified in &lt;em&gt;GridWebServiceSelectRequest.Columns&lt;/em&gt;.
&lt;br /&gt;
&lt;br /&gt;
The select response can now also contain hierarchical data, with rows containing more rows defined on the second (or third, etc) &lt;em&gt;GridLevel&lt;/em&gt;. To keep on topic, I will write more on this particular functionality at a later date.
&lt;br /&gt;
&lt;br /&gt;
Cheers, and thanks for stopping by!
&lt;br /&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx&amp;amp;;subject=Grid+Configuration+via+Web+Service" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx&amp;amp;;title=Grid+Configuration+via+Web+Service" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx&amp;amp;title=Grid+Configuration+via+Web+Service" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/06/13/grid-configuration-via-web-service.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=19796" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/ASP.NET+AJAX/default.aspx">ASP.NET AJAX</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Grid/default.aspx">Grid</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/web+services/default.aspx">web services</category></item><item><title>AJAX With ASP.NET MVC and ComponentArt CallBack</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx</link><pubDate>Thu, 01 May 2008 18:08:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:18817</guid><dc:creator>Milos</dc:creator><slash:comments>3</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/18817.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=18817</wfw:commentRss><description>&lt;br /&gt;
Web.UI vNext (preview build included in attached project packages) will include, among other things, a new feature of the CallBack control which will allow it to become extremely useful for integrating AJAX functionality in web applications build on Microsoft&amp;rsquo;s new ASP.NET MVC framework.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;About Microsoft ASP.NET MVC&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
A few months ago, Microsoft announced a new, alternative framework for ASP.NET applications built around the &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;model-view-controller&lt;/a&gt; architecture pattern. Scott Guthrie &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/10/14/asp-net-mvc-framework.aspx"&gt;blogged about it&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx"&gt;described in detail&lt;/a&gt; how this framework operates. Though still in a preview stage, ASP.NET MVC has already generated a lot of buzz and interest, and promises to be an important factor for some types of web apps. However, ASP.NET MVC has no AJAX support out of the box.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;About ComponentArt CallBack&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
ComponentArt CallBack is a relatively simple ASP.NET control which contains HTML content and allows it to be updated asynchronously via AJAX calls back to the server. In a typical web form, the request is sent back to the page of origin and is handled by the control itself, which raises an event, allowing the developer to compose the content to be sent to the client.
&lt;br /&gt;
&lt;br /&gt;
A new feature introduced to CallBack for the next version of Web.UI is the client-side &lt;strong&gt;loadUrl&lt;/strong&gt; method. This method allows the control to asynchronously call up any URL and display the content returned within its element on the page. This feature is useful for all sorts of situations, including rapid integration of partial AJAX updates in web applications built on Microsoft&amp;rsquo;s ASP.NET MVC framework.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;ASP.NET MVC and ComponentArt CallBack&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
ASP.NET MVC request routing operates according to conventions for HTTP GET requests. Requests for pages are of the form &lt;em&gt;/Controller/Action/Id&lt;/em&gt;, and the logic of the application is built to follow this flow: the appropriate Controller accepts the request, and handles the requested action by performing the appropriate business logic (in conjunction with the Model) and passing resulting data to the appropriate View which is then rendered to the client.
&lt;br /&gt;
&lt;br /&gt;
This architecture is a complete departure from that of ASP.NET web forms, which is based on postbacks and persistence of control state. The traditional use of CallBack (by raising server-side events to handle a callback request) is no longer applicable. However, with the addition of the loadUrl method, CallBack fits perfectly into the ASP.NET MVC architecture and provides the easiest and most integrated way of performing partial AJAX updates in an ASP.NET MVC application.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;How it Works&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
When designing functionality that is to be useful for ASP.NET MVC apps, we found that less is more. Since the MVC model forces us to drop most of the complexities of the ASP.NET web form life cycle, control state and server-side events, we are left with just the basics of HTTP. In this case, that is all we need, and it is also the best way to seamlessly integrate into the MVC way of doing things.
&lt;br /&gt;
&lt;br /&gt;
CallBack&amp;#39;s &lt;strong&gt;loadUrl&lt;/strong&gt; method causes CallBack&amp;rsquo;s content to be loaded from the given URL, which, of course, can follow MVC conventions. We are therefore able to have a CallBack control on an MVC View Page (say, CallBack1), get it rendered to the client, and from that point, only interact with it on the client side, to perform actions and load new content, with typical calls like these:
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;CallBack1.loadUrl(&amp;#39;/Search/Beverages/23&amp;#39;);
CallBack1.loadUrl(&amp;#39;/Products/List/Beverages&amp;#39;);
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
On the server, layout is organized as a standard ASPX View, with distinct parts encapsulated in ASCX views.
&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://www.componentart.com/blogs/milos/images/MVC_CallBack_Diagram_1.png" /&gt;
&lt;br /&gt;
&lt;br /&gt;
After the initial ASPX view is loaded, those parts of it which are encapsulated in ASCX views (and placed inside instances of ComponentArt CallBack) can be updated asynchronously.
&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://www.componentart.com/blogs/milos/images/MVC_CallBack_Diagram_2.png" /&gt;
&lt;br /&gt;
&lt;br /&gt;
Organizing content areas in ASCX views is the key component of our MVC AJAX solution.
&lt;br /&gt;
&lt;br /&gt;
The loadUrl method also takes an optional second parameter, POST data. If data needs to be sent that is not part of the URL (including the optional query string), it can be combined into a POST data string on the client (in the form &amp;quot;name1=value1&amp;amp;name2=value2&amp;quot;) and passed to loadUrl. It will be available in the MVC controller as part of the Request.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Examples&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
To illustrate these ideas, I include two examples below. With these web application projects, I have tried to demonstrate how Web.UI controls can be used in the context of MVC, including how partial AJAX updates can be performed with the CallBack control while maintaining the full MVC pattern. There are two separate applications:
&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;a href="http://www.componentart.com/blogs/milos/files/MvcChartGallery.zip"&gt;MvcChartGallery&lt;/a&gt;&lt;/em&gt;
&lt;br /&gt;
&lt;br /&gt;
This ASP.NET MVC web application is an adaptation of a typical application dealing with hierarchical data, featuring ComponentArt Web.UI controls. The architecture of the web application uses simple one-time rendering of the controls, taking them out of the paradigm of web forms. Interaction with the controls causes full-page refreshes with appropriate MVC routing. Context data is passed in URL query parameters.
&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;a href="http://www.componentart.com/blogs/milos/files/MvcAjaxChartGallery.zip"&gt;MvcAjaxChartGallery&lt;/a&gt;&lt;/em&gt;
&lt;br /&gt;
&lt;br /&gt;
This ASP.NET MVC web application is a reworking of the above example which encapsulates autonomous areas of the UI into MVC User Control Views, which are in turn placed inside instances of ComponentArt CallBack, allowing them to be updated independently and asynchronously (see diagram 2). Most importantly, these partial updates are HTTP requests MVC User Control Views and are fully routed through MVC. They can be treated in the same way as any other MVC request, and application logic does not need to do anything special to allow for this asynchronous operation, nor indeed to be aware of it at all.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
Though still in an early preview stage, ASP.NET MVC has attracted a lot of interest and shows a lot of promise to grow into an important web technology. However, as of yet, ASP.NET MVC has no built-in AJAX support. Despite its divorce from web forms, applications built on ASP.NET MVC can still utilize rich ComponentArt Web.UI controls, and use the CallBack control, in particular, to quickly and easily add AJAX functionality in a way that seamlessly fits into the MVC pattern.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx&amp;amp;;subject=AJAX+With+ASP.NET+MVC+and+ComponentArt+CallBack" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx&amp;amp;;title=AJAX+With+ASP.NET+MVC+and+ComponentArt+CallBack" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx&amp;amp;title=AJAX+With+ASP.NET+MVC+and+ComponentArt+CallBack" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/05/01/asp-net-mvc-and-ajax.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=18817" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/CallBack/default.aspx">CallBack</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/mvc/default.aspx">mvc</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>TreeView and Web Services</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx</link><pubDate>Wed, 23 Apr 2008 17:49:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:18564</guid><dc:creator>Milos</dc:creator><slash:comments>4</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/18564.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=18564</wfw:commentRss><description>&lt;br /&gt;
In my &lt;a href="http://www.componentart.com/blogs/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx"&gt;previous post&lt;/a&gt;, I talked about the web service functionality that&amp;#39;s common to all ComponentArt navigation controls. I focused on common features that are present in many different controls, especially in this case, but this approach was unfair to one control. With its ability to load chunks of data on demand, TreeView is the odd man out, supporting everything that other navigation controls do, but adding its own unique twist.
&lt;br /&gt;
&lt;br /&gt;
Like the other navigation controls, TreeView has control-level &lt;strong&gt;WebService&lt;/strong&gt; and 
&lt;strong&gt;WebServiceMethod&lt;/strong&gt; properties. These determine which ASP.NET AJAX registered web service will be called, and which method of that service, when nodes are retrieved. For the initial data load, the behaviour is identical to Menu, TabStrip or NavBar. What TreeView can do that others can not is to only load some nodes initially, letting user actions determine what else gets loaded and when. Essentially, TreeView is able to operate in load-on-demand mode with web services.
&lt;br /&gt;
&lt;br /&gt;
To return load-on-demand nodes (parent nodes with no child nodes pre-loaded), simply set their 
&lt;strong&gt;UseWebService&lt;/strong&gt; property to true. This will notify TreeView to consider these nodes to be parent nodes, and to call the web service again when they are expanded, to load their child nodes. When that happens, the same WebServiceMethod will be called, but with a twist: the
&lt;strong&gt;TreeViewWebServiceRequest&lt;/strong&gt; object that is passed in will have its &lt;strong&gt;Node&lt;/strong&gt; property set to the node that requires data. Based on the Text, Value or ID of this node, appropriate new nodes can be created and returned, as they would normally, from the web service method. Note that these child nodes can also have their UseWebService property set to true.
&lt;br /&gt;
&lt;br /&gt;
After a web service call completes, the client-side event also exposes the node for which the call was made, in addition to the &lt;strong&gt;customData&lt;/strong&gt; property common to all navigation controls. Here&amp;#39;s an overview of the client-side &lt;strong&gt;TreeViewNodeWebServiceCompleteEventArgs&lt;/strong&gt; class:
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;function TreeView1_webServiceComplete(sender, eventArgs)
{
  var node = eventArgs.get_node();
  
  if(node)
  {
    alert(&amp;#39;Completed web service call for node &amp;#39; + node.get_text());
  }
  else
  {
    alert(&amp;#39;Completed web service call for top level data.&amp;#39;);
  }
  
  var customData = eventArgs.get_customData();
  
  if(customData)
  {
    alert(&amp;#39;Web service call returned custom data: &amp;#39; + customData);
  }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
You can see an example of this functionality online with the &lt;a href="http://www.componentart.com/webui/demos/demos_technology-showcase/web-services_ajax/treeview_loadFromWebService/default.aspx"&gt;TreeView Web Service Load-on-demand sample&lt;/a&gt;. Please note that this functionality is fully available only as of Web.UI 2008.1 SP1, released on April 23rd 2008.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Summary&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
To recap, since TreeView can load node-specific partial data through web services (unlike other navigation controls, which can only load all the items at once), its related API is a superset of, say, that of Menu. 
&lt;strong&gt;TreeViewWebServiceRequest&lt;/strong&gt; includes the &lt;strong&gt;Node&lt;/strong&gt; property (null for initial, top-level loading), 
&lt;strong&gt;TreeViewNode&lt;/strong&gt; has the &lt;strong&gt;UseWebService&lt;/strong&gt; boolean, and the client-side &lt;strong&gt;TreeViewWebServiceCompleteEventArgs&lt;/strong&gt; class includes a 
&lt;strong&gt;node&lt;/strong&gt; property. These extensions enable efficient load-on-demand functionality built entirely on ASP.NET AJAX web services.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx&amp;amp;;subject=TreeView+and+Web+Services" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx&amp;amp;;title=TreeView+and+Web+Services" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx&amp;amp;title=TreeView+and+Web+Services" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/23/treeview-and-web-services.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=18564" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/treeview/default.aspx">treeview</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/web+services/default.aspx">web services</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Load+on+demand/default.aspx">Load on demand</category></item><item><title>Web.UI Navigation Controls and Web Services</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx</link><pubDate>Tue, 01 Apr 2008 17:45:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:17977</guid><dc:creator>Milos</dc:creator><slash:comments>4</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/17977.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=17977</wfw:commentRss><description>&lt;br /&gt;

It&amp;#39;s been some time now since we first started introducing client-side integration with ASP.NET AJAX web services into our controls. The first foray was the ability of Grid to bind directly to JavaScript object arrays, allowing it to directly load JSON data returned from a web service, and continue running in client mode (&lt;a href="http://www.componentart.com/webui/demos/demos_technology-showcase/web-services_ajax/grid_loadFromWebService/default.aspx"&gt;see demo&lt;/a&gt;). The interest that this generated prompted the next big wave: Grid&amp;rsquo;s WebService running mode (&lt;a href="http://www.componentart.com/webui/demos/demos_technology-showcase/web-services_ajax/grid_webServiceRunningMode/default.aspx"&gt;see demo&lt;/a&gt;) and web service functionality in all the major navigation controls: TreeView, Menu, TabStrip, NavBar and ToolBar (&lt;a href="http://www.componentart.com/webui/demos/demos_technology-showcase/web-services_ajax/web_serviceCreation/default.aspx"&gt;see demo&lt;/a&gt;).
&lt;br /&gt;&lt;br /&gt;

In the latest iteration of Web.UI (2008.1) we standardized client-side events relating to web service calls across this group of controls, and added the ability to pass custom data to and from the web services. Each &lt;em&gt;*WebServiceRequest&lt;/em&gt; and &lt;em&gt;*WebServiceResponse&lt;/em&gt; class now has a &lt;strong&gt;CustomParameter&lt;/strong&gt; property.
&lt;br /&gt;&lt;br /&gt;

In this blog post, I want to illustrate how this custom data can be bounced around using standard client-side and server-side properties and client events.
&lt;br /&gt;&lt;br /&gt;

Take as an example a Menu control, pointed at an ASP.NET Web Service:
&lt;br /&gt;&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;&amp;lt;ComponentArt:Menu runat=&amp;quot;server&amp;quot; ID=&amp;quot;Menu1&amp;quot;
  WebService=&amp;quot;MyService&amp;quot;
  WebServiceMethod=&amp;quot;GetItems&amp;quot;
  WebServiceCustomParameter=&amp;quot;Blue&amp;quot;
  ... /&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;

In the above example, we are telling Menu to call the WebMethod &lt;strong&gt;GetItems&lt;/strong&gt; of the service &lt;strong&gt;MyService&lt;/strong&gt;, and to set the initial value of its WebServiceCustomParameter to &amp;quot;Blue&amp;quot;. When the Menu loads on the client, it will do just that. Let&amp;rsquo;s see how we can access the custom parameter in the web service:
&lt;br /&gt;&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;[System.Web.Script.Services.ScriptService]
[WebService(Namespace = &amp;quot;http://tempuri.org/&amp;quot;)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class MyService : System.Web.Services.WebService
{
  [WebMethod]
  public MenuWebServiceResponse GetItems(MenuWebServiceRequest request)
  {
    // Create a response object.
    MenuWebServiceResponse response = new MenuWebServiceResponse();

    // For this example, we will only return one item,
    // with the Text matching the custom parameter given to us.
    MenuItem newItem = new MenuItem(); 
    newItem.Text = request.CustomParameter;
    response.AddItem(newItem);

    // We will also return some custom data from the server.
    // Let&amp;rsquo;s make it the current time.
    response.CustomParameter = DateTime.Now.ToString();

    // Send the data back.
    return response;
  }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
When this Menu loads on the client, it will load up the web service data, which will result in a single menu item entitled &amp;quot;Blue&amp;quot;. We can always re-load data from the client by calling Menu&amp;rsquo;s client-side &lt;strong&gt;loadFromWebService&lt;/strong&gt; method. We can also change the WebServiceCustomParameter on the client before doing so. For example, the following JavaScript would result in the Menu reloading its data and ending up with a single item entitled &amp;quot;Red&amp;quot;:
&lt;br /&gt;&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;Menu1.set_webServiceCustomParameter(&amp;#39;Red&amp;#39;);
Menu1.loadFromWebService();
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
This mechanism should enable unlimited reloading of data for any navigation control based on custom data passed from the client. One last thing remains to be answered: how do we access that custom data (the server time) we sent back to the client from the web service? This is where client events come in. If we want access to this custom data, we&amp;rsquo;ll have to hook the &lt;strong&gt;WebServiceComplete&lt;/strong&gt; client event:
&lt;br /&gt;&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;&amp;lt;ComponentArt:Menu runat=&amp;quot;server&amp;quot; ID=&amp;quot;Menu1&amp;quot; ... &amp;gt;
  &amp;lt;ClientEvents&amp;gt;
    &amp;lt;WebServiceComplete EventHandler=&amp;quot;Menu1_WebServiceComplete&amp;quot; /&amp;gt;
  &amp;lt;/ClientEvents&amp;gt;
&amp;lt;/ComponentArt:Menu&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
In the event handler, we can access the custom data through the event arguments parameter:
&lt;br /&gt;&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;function Menu1_WebServiceComplete(sender, eventArgs)
{
  alert(&amp;#39;Loaded items from web service, along with this custom data: &amp;#39; +
    eventArgs.get_customData());
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
I hope that explains this exciting new functionality and that you find it as neat and useful as we do. Do let us know what you think and how we can build on this in the future.
&lt;br /&gt;&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx&amp;amp;;subject=Web.UI+Navigation+Controls+and+Web+Services" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx&amp;amp;;title=Web.UI+Navigation+Controls+and+Web+Services" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx&amp;amp;title=Web.UI+Navigation+Controls+and+Web+Services" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/04/01/web-ui-navigation-controls-and-web-services.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=17977" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/web+services/default.aspx">web services</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/custom+parameter/default.aspx">custom parameter</category></item><item><title>Introducing ComponentArt Upload</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx</link><pubDate>Fri, 28 Mar 2008 12:21:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:17839</guid><dc:creator>Milos</dc:creator><slash:comments>3</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/17839.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=17839</wfw:commentRss><description>
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;ComponentArt Web.UI 2008.1 includes one new addition to the
library of controls: &lt;a href="http://www.componentart.com/webui/demos/demos_control-specific/upload/features/core_features/webform1.aspx"&gt;Upload&lt;/a&gt;. ComponentArt Upload is a file upload control with
all the high-end AJAX
and client-centric functionality one should expect from a Web.UI control.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p class="MsoNormal"&gt;The control comes with a custom server-side HTTP module for
optimally processing the file upload, and an HTTP handler which provides upload
progress information and otherwise enables communication between the module and
the control on the client.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p class="MsoNormal"&gt;On the client, progress feedback is provided using client
templates, in which all the metrics related to the upload (percentage, elapsed
time, file sizes, speed, filenames, etc.) can be accessed and displayed in any
layout the developer defines. File input fields (there can be more than one)
are also formatted and styled using client templates, again with unlimited
visual potential.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p class="MsoNormal"&gt;To configure an Upload control, the HTTP module and the
handler must be added to the application&amp;rsquo;s web.config file:&lt;/p&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;&amp;lt;httpModules&amp;gt;
 &amp;lt;add type=&amp;quot;ComponentArt.Web.UI.UploadModule, ComponentArt.Web.UI&amp;quot;
  name=&amp;quot;ComponentArtUploadModule&amp;quot;/&amp;gt;
&amp;lt;/httpModules&amp;gt;
&lt;br /&gt;
&amp;lt;httpHandlers&amp;gt;
 &amp;lt;add verb=&amp;quot;*&amp;quot;
  type=&amp;quot;ComponentArt.Web.UI.UploadProgressHandler, ComponentArt.Web.UI&amp;quot;
  path=&amp;quot;ComponentArtUploadProgress.axd&amp;quot; /&amp;gt;
&amp;lt;/httpHandlers&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Once this back-end infrastructure is in place, an Upload
control can be placed on a page of the application:&lt;/p&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;&amp;lt;ComponentArt:Upload runat=&amp;rdquo;server&amp;rdquo; ID=&amp;rdquo;Upload1&amp;rdquo; TempFileFolder=&amp;rdquo;c:\temp\uploads&amp;rdquo; ... /&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;

&lt;p class="MsoNormal"&gt;The Upload control writes files to disk as they come in, to
prevent the waste of memory on the server, so &lt;span style="font-weight:bold;"&gt;TempFileFolder &lt;/span&gt;must be set on the
control, to the absolute path of a folder where uploads are to be stored as
they happen.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p class="MsoNormal"&gt;When an upload completes, the file(s) can be handled via the
control&amp;rsquo;s Uploaded event, or by setting the &lt;span style="font-weight:bold;"&gt;DestinationFolder &lt;/span&gt;property, which
will cause successful uploads to automatically be moved to the specified
folder. In the latter case, automatic validation can also be performed before moving,
using the &lt;span style="font-weight:bold;"&gt;AllowedFileExtensions &lt;/span&gt;and &lt;span style="font-weight:bold;"&gt;AllowedMimeTypes &lt;/span&gt;properties.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p class="MsoNormal"&gt;Styling of the control is done almost exclusively with
client templates. The input area, as well as the progress feedback, can both be
client-templated. In the latter case, extensive information on upload progress
is available to be used in the template.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p class="MsoNormal"&gt;The progress client template (specified using the
&lt;span style="font-weight:bold;"&gt;ProgressClientTemplateId &lt;/span&gt;property) is rendered in a popup over the upload
control by default. If the &lt;span style="font-weight:bold;"&gt;ProgressDomElementId &lt;/span&gt;property is set, the client
template will instead be rendered into the specified DOM element, allowing
external controls to be used for progress feedback, such as the ComponentArt
Dialog control.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;


&lt;p&gt;The value of the boolean &lt;span style="font-weight:bold;"&gt;AutoPostBack &lt;/span&gt;property determines whether a postback will occur when the upload completes. If false, a callback is performed instead, and Upload&amp;#39;s server-side event handler (or DestinationFolder logic) is still executed right away, without the page visibly reloading.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;We hope you find this new control useful. We&amp;#39;re pretty excited about what it brings to the field and the bar it sets for rich client-side styling and formatting. Try it out and let us know what you think.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;You can start by checking out the &lt;a href="http://www.componentart.com/webui/demos/demos_control-specific/upload/features/core_features/webform1.aspx"&gt;Upload samples online&lt;/a&gt;.&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx&amp;amp;;subject=Introducing+ComponentArt+Upload" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx&amp;amp;;title=Introducing+ComponentArt+Upload" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx&amp;amp;title=Introducing+ComponentArt+Upload" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/28/introducing-componentart-upload.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=17839" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Upload/default.aspx">Upload</category></item><item><title>Toronto Code Camp 2008</title><link>http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx</link><pubDate>Mon, 03 Mar 2008 19:07:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:16259</guid><dc:creator>Milos</dc:creator><slash:comments>0</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/16259.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=16259</wfw:commentRss><description>
&lt;p class="MsoNormal"&gt;Two days ago, on Saturday, I attended &lt;a href="http://www.torontocodecamp.net/"&gt;Toronto Code Camp 2008&lt;/a&gt;,
the third such event organized in our fair city. It was my first time at a
Code Camp and I had a good time and learned a lot. In addition to attending some
very interesting presentations and chatting with people from the ASP.NET community, I got to speak as well! My talk was about how ASP.NET AJAX exposes web services on the client, and how that can be connected with &amp;quot;client-centric&amp;quot; controls, such as those in Web.UI. After some introductory examples of accessing web services from client-side code, I demonstrated how ComponentArt
TreeView and Grid can load data directly from web services using the ASP.NET
AJAX.&lt;/p&gt;
&lt;br /&gt;
&lt;p class="MsoNormal"&gt;Those interested can download the (simple, introductory) code samples &lt;a href="http://www.componentart.com/blogs/milos/files/CodeCampDemos.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;
&lt;br /&gt;
&lt;p class="MsoNormal"&gt;P.S. After the talk, Joel Tulloch pointed out
to me that it isn&amp;rsquo;t necessary to mirror the server-side classes on the client by
hand. We can use the GenerateScriptType attribute for this, as he describes on
&lt;a href="http://www.jtulloch.com/blog/post/2008/03/Instantiating-Server-Side-Objects-From-the-Client-Using-ASPNET-AJAX.aspx"&gt;his blog&lt;/a&gt;. Very neat stuff.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx&amp;amp;;subject=Toronto+Code+Camp+2008" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx&amp;amp;;title=Toronto+Code+Camp+2008" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx&amp;amp;title=Toronto+Code+Camp+2008" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2008/03/03/toronto-code-camp-2008.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=16259" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/ASP.NET+AJAX/default.aspx">ASP.NET AJAX</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/code+camp/default.aspx">code camp</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/web+services/default.aspx">web services</category></item><item><title>New Grid Feature: CallbackParameter</title><link>http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx</link><pubDate>Wed, 19 Dec 2007 23:26:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:12606</guid><dc:creator>Milos</dc:creator><slash:comments>6</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/12606.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=12606</wfw:commentRss><description>A common scenario that our users encounter with the Grid is the need to populate it with different data depending on client-side context &amp;ndash; for instance, a dropdown option or a TreeView selection. Very often, this situation is solved by to setting Grid to Server or Client running mode and wrapping it in a CallBack control, and then using the CallBack to send custom parameters back to the server and to refresh the Grid.
&lt;br /&gt;
&lt;br /&gt;

This has worked well for many, but is not without its limitations, mostly having to do with CallBack&amp;rsquo;s inability to maintain state across callbacks. It also seems somehow wrong and wasteful to approach things this way and completely ignore Grid&amp;rsquo;s own ability to issue callbacks, and maintain its own state.
&lt;br /&gt;
&lt;br /&gt;

To remedy this slightly awkward situation, we&amp;rsquo;ve introduced and small (but hopefully important) new feature to Grid as part of Web.UI 2007.2 SP1: the CallbackParameter property. This property can be set on the server or the client, and is sent back with every callback issued by the Grid. A Grid in CallBack running mode exposes this value on the server in time for every server-side event, and the value will mirror that on the client. So, where before we may have done something like this:
&lt;br /&gt;
&lt;br /&gt;

&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;CallBack1.callback(&amp;lsquo;mailbox&amp;rsquo;);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;

we would now do away with the CallBack control altogether, and do this instead:
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;Grid1.set_callbackParameter(&amp;lsquo;mailbox&amp;rsquo;);&lt;br /&gt;Grid1.callback();&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;

Conditional logic on the server can then do the right thing based on the value of Grid1.CallbackParameter. To further facilitate this parameter-based loading, we&amp;rsquo;ve added two more server-side Grid events: BeforeCallback and AfterCallback. These are raised before and after (respectively) all the other events raised during a Grid callback request.
&lt;br /&gt;
&lt;br /&gt;

Hope you find this useful! Let us know what you think.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;

&lt;em&gt;
Note: This feature is available as of Grid 2007.2 SP1, available Dec 17. 2007.
&lt;/em&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx&amp;amp;;subject=New+Grid+Feature%3a+CallbackParameter" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx&amp;amp;;title=New+Grid+Feature%3a+CallbackParameter" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx&amp;amp;title=New+Grid+Feature%3a+CallbackParameter" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/19/Grid_2C00_-Web.UI_2C00_-CallBack_2C00_-CallbackParameter.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=12606" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/CallBack/default.aspx">CallBack</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Grid/default.aspx">Grid</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/New+Feature/default.aspx">New Feature</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/CallbackParameter/default.aspx">CallbackParameter</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category></item><item><title>Web Service Data Loading with Navigation Controls</title><link>http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx</link><pubDate>Tue, 18 Dec 2007 16:18:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:12626</guid><dc:creator>Milos</dc:creator><slash:comments>0</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/12626.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=12626</wfw:commentRss><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Previously, I have written about Grid&amp;rsquo;s new WebService running mode, which allows Grid to communicate with an ASP.NET AJAX web service directly from the client, and do all its data loading through it, including paging, sorting, filtering, etc. This powerful functionality is also available on ComponentArt navigation controls: TreeView, Menu, NavBar, TabStrip and ToolBar. All of these have the ability to load their data from an ASP.NET AJAX web service. TreeView, furthermore, has the ability to load data for each node on demand. Since this functionality is a superset of the simple ability to fetch all the data at once, I&amp;rsquo;ll outline the more complex case here.
&lt;br /&gt;
&lt;br /&gt;

- On the server, we use the WebService and WebServiceMethod properties to set the name of the registered web service to use, as well as the name of the method to invoke to retrieve node data.
&lt;br /&gt;
&lt;br /&gt;

- The service WebMethod refered to by the control&amp;rsquo;s WebServiceMethod property should be implemented with the following signature:
&lt;br /&gt;
&lt;br /&gt;

&lt;em&gt;public TreeViewWebServiceResponse MethodName(TreeViewWebServiceRequest request)&lt;/em&gt;
&lt;br /&gt;
&lt;br /&gt;

The above example is for TreeView &amp;ndash; for other controls, the appropriate types should be used, eg. TabStripWebServiceResponse and TabStripWebServiceRequest for TabStrip.
&lt;br /&gt;
&lt;br /&gt;

- The method&amp;rsquo;s return value (a *WebServiceResponse) should contain the nodes to be sent to the control.
&lt;br /&gt;
&lt;br /&gt;

At this point, the work of defining a web service data source for a navigation control is complete. With the above setup, the control will fetch its data from the specified web service by invoking the specified method.
&lt;br /&gt;
&lt;br /&gt;

With TreeView, we often wish to configure data loading using an on-demand mechanism. This means that a node&amp;rsquo;s children are loaded only when that node is expanded and no sooner. To achieve this, we only need one additional step:
&lt;br /&gt;
&lt;br /&gt;

- Instead of populating a TreeViewNode with its child nodes, set its UseWebService property to &lt;em&gt;true&lt;/em&gt; to specify that the web service should be used to fetch its child nodes. When this is done, the same WebServiceMethod will be invoked as for the root nodes, but the TreeViewWebServiceRequest&amp;rsquo;s Node property will be set to the TreeViewNode which needs to be populated.
&lt;br /&gt;
&lt;br /&gt;

That&amp;rsquo;s all there is to it.
&lt;br /&gt;
&lt;br /&gt;

Note: All the navigation controls also have a WebServiceCustomParameter which can be set on the server or the client, and which is sent back as part of every *WebServiceRequest. This should allow for custom context-dependant data loading.
&lt;br /&gt;
&lt;br /&gt;

For a simple demo of this functionality, check out the &lt;a href="http://www.componentart.com/webui/demos/demos_technology_showcase/web-services_ajax/web_serviceCreation/default.aspx"&gt;Web Service Creation sample&lt;/a&gt; on our site. For a look at web service-driven TreeView load-on-demand, take a look at &lt;a href="http://www.componentart.com/webui/demos/demos_technology_showcase/web-services_ajax/treeview_loadFromWebService/default.aspx"&gt;this TreeView sample&lt;/a&gt;. A useful real-world application using TreeView and Grid, build entirely on web services, can be seen in the &lt;a href="http://www.componentart.com/webui/demos/demos_technology_showcase/web-services_ajax/full_webServiceApp/default.aspx"&gt;Full Web Service Application&lt;/a&gt; sample.
&lt;br /&gt;
&lt;br /&gt;

&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx&amp;amp;;subject=Web+Service+Data+Loading+with+Navigation+Controls" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx&amp;amp;;title=Web+Service+Data+Loading+with+Navigation+Controls" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx&amp;amp;title=Web+Service+Data+Loading+with+Navigation+Controls" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/12/18/web-service-data-loading-with-navigation-controls.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=12626" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/ASP.NET+AJAX/default.aspx">ASP.NET AJAX</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web+Service/default.aspx">Web Service</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/navigation/default.aspx">navigation</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/treeview/default.aspx">treeview</category></item><item><title>New Grid Feature: WebService Running Mode</title><link>http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx</link><pubDate>Wed, 14 Nov 2007 16:30:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:9354</guid><dc:creator>Milos</dc:creator><slash:comments>8</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/9354.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=9354</wfw:commentRss><description>&lt;br /&gt;
Version 2007.2 of ComponentArt Grid includes, among other goodies, an exciting new feature: WebService running mode. We think it should be very useful for a lot of people so, in this post, I want to introduce you to this feature and explain how it works.
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;What is it?&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
Those who have used Grid will be familiar with the notion of a &amp;ldquo;running mode&amp;rdquo;. Until this point, Grid could be used in three different modes: Server, Callback and Client. Setting the RunningMode property to one of these determines whether Grid performs its data-related actions (paging, sorting, filtering, etc) via postbacks, callbacks, or entirely on the client.
&lt;br /&gt;
&lt;br /&gt;
The most efficient way of interfacing with large data sets was always the callback mode, but it had one downside: callbacks were made to the same ASPX page which houses the control, so each callback incurred the overhead of the ASP.NET page life cycle and auxiliary init code.
&lt;br /&gt;
&lt;br /&gt;
The new WebService running mode allows Grid to perform data operations via calls to an ASP.NET AJAX web service. We feel that this system provides maximal efficiency and design elegance by allowing us to completely separate our data access code from the ASP.NET page which houses the layout. 
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;How do I use it?&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
To use web service running mode, start by setting Grid&amp;rsquo;s RunningMode property to WebService.
&lt;br /&gt;
&lt;br /&gt;
Then, set the WebService property to the name of the ASP.NET AJAX web service to use. You will also need to set the names of that service&amp;rsquo;s WebMethods to use for fetching items, or updating and inserting them. For this, use the WebService*Method properties (eg. WebServiceSelectMethod).
&lt;br /&gt;
&lt;br /&gt;
The web service should be registered with the ScriptManager in the usual way, and the specified methods should have standard signatures:
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;GridWebServiceSelectResponse SelectMethod(GridWebServiceSelectRequest req)&lt;br /&gt;bool UpdateMethod (GridWebServiceUpdateRequest req)&lt;br /&gt;bool InsertMethod(GridWebServiceInsertRequest req)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;strong&gt;Selection&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
Most of the usual interaction with a Grid will be done through the select method, whose logic will handle all paging, sorting and filtering. Whenever a new set of records is required on the client this method will be invoked with all the necessary information to fetch the appropriate records. The GridWebServiceSelectRequest will contain the required page index, page size, sort order and any conditional filters. The response should contain all the necessary records (objects with appropriately named properties), and information about the total number of records, for purposes of paging.
&lt;br /&gt;
&lt;br /&gt;
Here&amp;rsquo;s an example of a simple select method which handles paging and sorting:
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;    [WebMethod]&lt;br /&gt;    public GridWebServiceSelectResponse GetRecords(GridWebServiceSelectRequest request)&lt;br /&gt;    {&lt;br /&gt;      DataSet oDS = FetchAllData(); // implemented elsewhere, returns all records&lt;br /&gt;      DataView oView = oDS.Tables[0].DefaultView;&lt;br /&gt;&lt;br /&gt;      if(request.SortField != &amp;quot;&amp;quot;) oView.Sort = request.SortField + &amp;quot; &amp;quot; + request.SortOrder;&lt;br /&gt;&lt;br /&gt;      List list = new List();&lt;br /&gt;&lt;br /&gt;      int pageSize = request.PageSize;&lt;br /&gt;      int startRec = request.CurrentPageIndex * pageSize;&lt;br /&gt;&lt;br /&gt;      for (int i = startRec; i &amp;lt; Math.Min(startRec + pageSize, oView.Count); i++)&lt;br /&gt;      {&lt;br /&gt;        Message msg = new Message();&lt;br /&gt;&lt;br /&gt;        msg.Subject = (string)oView[i][&amp;quot;Subject&amp;quot;];&lt;br /&gt;        msg.LastPostDate = (DateTime)oView[i][&amp;quot;LastPostDate&amp;quot;];&lt;br /&gt;        msg.TotalViews = (int)oView[i][&amp;quot;TotalViews&amp;quot;];&lt;br /&gt;        msg.StartedBy = (string)oView[i][&amp;quot;StartedBy&amp;quot;];&lt;br /&gt;&lt;br /&gt;        list.Add(msg);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      GridWebServiceSelectResponse response = new GridWebServiceSelectResponse();&lt;br /&gt;&lt;br /&gt;      response.Items = list;&lt;br /&gt;      response.RecordCount = oView.Count;&lt;br /&gt;    &lt;br /&gt;      return response;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;strong&gt;Inserting and Updating&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
Updating records and inserting new ones is done in very much the same way as selection. However, since these actions only affect one record, the request is a lot simpler and basically contains only the data for the item in question. The relevant classes are GridWebServiceInsertRequest and GridWebServiceUpdateRequest.
&lt;br /&gt;
&lt;br /&gt;
We hope this mechanism will allow for totally UI-independent data handling that communicates with the client-side Grid in the most efficient possible way. Because Grid is able to redraw itself on the client, there is no need to ever go back to the original ASP.NET page after it has launched the Grid. Developing this approach should be the way forward in taking client-centric web apps to the next level.
&lt;br /&gt;
&lt;br /&gt;
Let us know what you think!
&lt;br /&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx&amp;amp;;subject=New+Grid+Feature%3a+WebService+Running+Mode" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx&amp;amp;;title=New+Grid+Feature%3a+WebService+Running+Mode" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx&amp;amp;title=New+Grid+Feature%3a+WebService+Running+Mode" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/14/new-grid-feature-webservice-running-mode.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=9354" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web+Service/default.aspx">Web Service</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Grid/default.aspx">Grid</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/AJAX/default.aspx">AJAX</category></item><item><title>SpellCheck Client-side API</title><link>http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx</link><pubDate>Wed, 07 Nov 2007 18:55:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:8522</guid><dc:creator>Milos</dc:creator><slash:comments>2</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/8522.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=8522</wfw:commentRss><description>&lt;p&gt;The SpellCheck control, like most others in Web.UI, includes a powerful client-side API. The philosophy behind SpellCheck&amp;rsquo;s design is that as little as possible should be baked right into the control when it comes to visual interface, and that custom user experiences should be made as easy as possible via a powerful and versatile client-side API.
&lt;br /&gt;
&lt;br /&gt;

Below are some examples.
&lt;br /&gt;
&lt;br /&gt;
	
To check some text and see how many errors there are, we can do the following:&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;var text = &amp;quot;This is some text with spleling misteaks in it.&amp;quot;&lt;br /&gt;&lt;br /&gt;function spellComplete(result)&lt;br /&gt;{&lt;br /&gt;  alert(&amp;#39;SpellCheck complete: &amp;#39; + Spell1.get_numErrors() + &amp;#39; errors found.&amp;#39;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Spell1.Check(text, spellComplete);&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;
&lt;br /&gt;

Continuing from the above example, this is how we can go through the errors and see what they are:&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;for(var i = 0; i &amp;lt; Spell1.get_numErrors(); i++)&lt;br /&gt;{&lt;br /&gt;  alert(&amp;#39;Error number &amp;#39; + i + &amp;#39; is: &amp;#39; + Spell1.getError(i));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;
&lt;br /&gt;
We can expand the loop above to show the user what some alternatives might be for each of those errors:&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;var currentError;&lt;/pre&gt;&lt;pre&gt;function suggestHandler(result)&lt;br /&gt;{&lt;br /&gt;   alert(&amp;#39;You typed\&amp;#39;&amp;#39; + currentError + &amp;#39;\&amp;#39; but maybe you meant to type one of these: &amp;#39; + result);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;for(var i = 0; i &amp;lt; Spell1.get_numErrors(); i++)&lt;br /&gt;{&lt;br /&gt;  currentError = Spell1.getError(i);&lt;br /&gt;  Spell1.getSuggestions(currentError, suggestHandler);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;
&lt;br /&gt;
We can also use the client-side API to change errors in the text right where they appear. For instance, we could alter the above to simply replace every misspelled word with the first suggestion returned by SpellCheck:&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="border:1px solid #808080;padding:10px;font-family:courier new;background-color:#e5e5e5;text-align:left;"&gt;
&lt;pre&gt;var currentErrorIndex;&lt;br /&gt;&lt;br /&gt;function suggestHandler(result)&lt;br /&gt;{&lt;br /&gt;   text = Spell1.Change(text, null, currentErrorIndex, result[0]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;for(var i = 0; i &amp;lt; Spell1.get_numErrors(); i++)&lt;br /&gt;{&lt;br /&gt;  currentErrorIndex = i;&lt;br /&gt;  Spell1.getSuggestions(currentError, suggestHandler);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;
&lt;br /&gt;
In the above example, we&amp;rsquo;ve been passing around the text variable, which we defined ourselves. When SpellCheck&amp;rsquo;s ControlToCheck property is set, null can be passed instead of text to any method that requires it &amp;ndash; the control will get the relevant text itself, and interventions will be made right on the text in question, whether it&amp;rsquo;s in a form field or any other DOM element.
&lt;/p&gt;&lt;p&gt;We hope you find this useful. Let us know what you think.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx&amp;amp;;subject=SpellCheck+Client-side+API" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx&amp;amp;;title=SpellCheck+Client-side+API" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx&amp;amp;title=SpellCheck+Client-side+API" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/07/spellcheck-client-side-api.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=8522" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/SpellCheck/default.aspx">SpellCheck</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/API/default.aspx">API</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/client-side/default.aspx">client-side</category></item><item><title>Introducing SpellCheck</title><link>http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx</link><pubDate>Tue, 06 Nov 2007 14:36:00 GMT</pubDate><guid isPermaLink="false">c19e7ad3-6f2a-44cb-a9a2-6a12e252d531:8437</guid><dc:creator>Milos</dc:creator><slash:comments>0</slash:comments><comments>http://www.componentart.com/BLOGS/milos/comments/8437.aspx</comments><wfw:commentRss>http://www.componentart.com/BLOGS/milos/commentrss.aspx?PostID=8437</wfw:commentRss><description>&lt;p&gt;&lt;br /&gt;
Version 2007.2 of Web.UI brings with it two new controls: Editor and SpellCheck. In this post, I will provide a brief overview of SpellCheck, describing its abilities and the design philosophy behind it.
&lt;br /&gt;
&lt;br /&gt;

SpellCheck, as its name suggests, is an ASP.NET control used for facilitating spellchecking on a web page. SpellCheck can be used to check the spelling of any textual content on a page, whether in an input field, text area, or any other element. It uses AJAX techniques to communicate efficiently with its server-side logic, and exposes a rich and versatile client-side API for controlling the checking process.
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;
Dialog-based Checking&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;

The most common way that people interface with spelling checkers is via a pop-up dialog. The dialog guides the user through the checking process, going through the errors in order and bringing up suggestions for each. When the process is done, the dialog closes.
&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;For an example of this UI, check out &lt;a href="http://www.componentart.com/webui/demos_2007.2/spellcheck/core_features/webform1.aspx"&gt;our dialog-based SpellCheck demo&lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;
SpellCheck&amp;rsquo;s client-side API includes an array of methods and events which were designed to facilitate such interaction, while imposing absolutely no restrictions on the nature of the dialog or its layout or styling.
&lt;br /&gt;
&lt;br /&gt;

Methods like dialogBegin, dialogChange and dialogIgnoreAll were designed to be invoked by buttons commonly found on spellchecking dialogs. Generic methods like getSuggestions are also used to move the process along. In our own example, we use this API to interface with SpellCheck using our own Dialog control. However, the same can be accomplished using any control or mechanism which invokes the dialog-related public methods.
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;
In-place Highlighting with Context Menus
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;

When the target being checked is a DOM element other than a form-field, checking can be done using in-place highlighting. This means that SpellCheck will actually intervene in the markup being targeted and highlight the words that are spelled incorrectly. When the user clicks on such a word, a context menu is displayed, offering a list of suggested words to replace the mistake.
Since the context menu (a ComponentArt Menu, naturally) is populated on the client as needed, it can be styled in any way in its server-side definition, and simply pointed to using SpellCheck&amp;rsquo;s ContextMenuId property.
&lt;br /&gt;
&lt;br /&gt;

This mechanism is often seen as more convenient than a dialog-based one, and requires no external code to put together. You can see an example of this UI in &lt;a href="http://www.componentart.com/webui/demos_2007.2/spellcheck/context_menu/webform1.aspx"&gt;our context-based SpellCheck demo&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;
Client-side API
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;

The above examples are only the most common ways the spell checking process is organized. Since SpellCheck exposes all the key components of the process via its client-side API, it should support any novel interface that is envisioned.
With methods like check, getSuggestions, change, ignore and addToDictionary, there are very few limitations to the kind of experience that can be designed around them.
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Up next: more on SpellCheck&amp;#39;s client-side API. Stay tuned.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx&amp;amp;;subject=Introducing+SpellCheck" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx&amp;amp;;title=Introducing+SpellCheck" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx&amp;amp;title=Introducing+SpellCheck" target="_blank" title = "Post http://www.componentart.com/BLOGS/milos/archive/2007/11/06/introducing-spellcheck.aspx"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.componentart.com/BLOGS/aggbug.aspx?PostID=8437" width="1" height="1"&gt;</description><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/Web.UI/default.aspx">Web.UI</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/SpellCheck/default.aspx">SpellCheck</category><category domain="http://www.componentart.com/BLOGS/milos/archive/tags/2007.2/default.aspx">2007.2</category></item></channel></rss>