Tag Archives: WCF RIA Services

WebUI Studio 2011 Goes Gold!

The past few weeks were probably the busiest days in this first quarter as we are preparing for the huge 2011 volume release. Even sparing a few minutes to write blogs seems to be uneasy to the team due to super tight schedules. Nevertheless, our diligent works are well paid off as we managed to (still) release on schedule. 

The wait is over! The highly-anticipated WebUI Studio 2011 finally goes gold today, which includes the new data controls lineup that have been made available in several beta releases. It delivers a total of 30 new controls for ASP.NET, Silverlight and WPF development – another fantastic release! To see what the new WebUI Studio has in store for you, please head to What’s New in WebUI Studio 2011.

Next, please refer to the following links for more details on the new release.

In addition, major sites such as Intersoft Support Site, Online Documentation   and ASP.NET live demos have been updated as well to reflect the new releases. Be sure to check out the updated ClientUI demos too where we have added around 80   business-inspiring samples with amazing user experiences. To try the demos now, jump to ClientUI live demos.

In this blog post, I will share a quick recap on the key highlight of the new release. In addition to many new exciting stuff as you can read in the 2011 Tour page, the new 2011 release is highly focused in improving the overall user experiences in an end-to-end approach – from the installation and getting started to licensing and deployment.

To that end, WebUI Studio 2011 now ships with a new installation experience that integrates with the operating system’s look and feel. So if you’re using Windows 7 with Aero-glass enabled, you will see the new WebUI Studio setup to use the same glass theme. The overall user interface has also been redesigned for simplicity and elegancy. To stimulate your appetite, let’s see some of the new installation shots below.

WebUI Studio 2011 New Installation Experiences

WebUI Studio 2011 New Installation Experiences

However, the new installation experience isn’t just about the glassy user interface. More importantly, the new WebUI Studio setup has been further simplified to require only a few clicks to complete a common installation – reducing from 8 to 4 in the total number of clicks. In this “automatic” setup mode, the installer detects your computer configuration and smartly decides the best settings to apply to your installation session. For instances, if you have Visual Studio 2011 installed, then all the samples and help files for Visual Studio 2010 will be automatically chosen.

Of course, you can still customize the installation the way you accustomed to, by checking the customize checkbox in the initial screen before hitting the Next button, see the screenshot below for a close-up.

WebUI Studio 2011 Setup Customization

All in all, WebUI Studio 2011 is our best release yet. It ships with a dramatically improved user experience, 12 new time-saving business project templates, native DevForce integration, and delivers over 30 new and essential business controls to the already comprehensive portfolio – positioning it as the developer’s top choice for all .NET application development needs.

Definitely there are so much exciting stuff to share in this new release, but I decided to not polluting this blog post with product-specific and new samples coverage. I’ll surely recap those topics in my next post. For now, download the new WebUI Studio if you haven’t done so.

Last but not least, we hope you enjoy the new release as much as we enjoy building it!

All the best,
Jimmy

UXGridView RC Adds MVVM Data Exporting, Multi Aggregates, Selectors, and more

After going through a series of technology preview releases,  UXGridView is finally topping off with the complete feature sets. Today, I’m excited to announce the immediate availability of UXGridView Release Candidate.

In case you missed the stories, UXGridView is Intersoft’s brand-new data grid built to handle the most demanding line-of-business development requirements – from server-side paging and filtering support, data editing and validation, batch update to data aggregates and data exporting. Each feature is thoughtfully engineered to work best with MVVM pattern implementation. UXGridView runs on both Silverlight and WPF with single identical markups. Learn more about UXGridView here.

In this post, I will share the key highlights of the new features implemented in the UXGridView RC. As defined in the roadmap that I posted in my blog post, the RC milestone will include advanced data-centric features such as data exporting, row virtualization improvements, multi aggregates, custom grouping logics, and a bunch of style selectors and template selectors.

Data Exporting the MVVM-way

In the previous CTPs, you have learned how UXGridView handles real-world data access scenarios like paging, filtering, data validation and editing – all implemented entirely with MVVM design pattern. In this RC release, UXGridView adds data exporting capability which you can implement using the solid MVVM pattern. Unlike other grids, the data exporting in UXGridView supports both server-side and client-side mode. The most advanced mode is the server-side data exporting which allows you to export all rows in the data source even though the UXGridView is paged.

Just because UXGridView supports displaying millions of rows, that doesn’t mean you should. In real-world scenarios, most users browse and look only for a piece of data at a time. So in most cases, you would enable the server-side paging in the UXGridView so it loads only a subset of data at a time. For instances, a Grid with the page size set to 20 will load only 20 rows per page. The data exporting, quite the opposite, requires all data to be fetched before the exporting can execute. That’s one of the key challenges that we managed to address in UXGridView, enabling data exporting to work in harmony with the server paging and other features using the MVVM pattern implementation.

To handle the server-side data operation consistently, we built the data exporting upon the same key component that powers the server paging and filtering, the QueryDescriptor. Perhaps you still recall, QueryDescriptor encapsulates the query definitions which consisted of FilterDescriptors, SortDescriptors and PageDescriptor. That’s just perfect because we can simply use the existing instance of the QueryDescriptor in the ViewModel, and perform re-query that doesn’t include the paging descriptor. If you need a refresh on QueryDescriptor, please head to Data-access the MVVM-way.

The best way to handle the data exporting using MVVM is to implement a DelegateCommand in the ViewModel and bind it to the ExportCommand, a new command property introduced in the RC release. In the Executed handler, you call a server query that returns complete data, and finally pass it to the collection in the ViewModel which is bound to the ExportItems property of UXGridView. Take a look at the following code snippet to learn how it’s done.

public class ServerExportingViewModel : ServerSideOperationViewModel
{
    public ServerExportingViewModel()
        : base()
    {
        this.CanUserExport = true;
        this.ExportCommand = new DelegateCommand(ExecuteExportCommand);
    }

    public void ExecuteExportCommand(object parameter)
    {
        QueryDescriptor exportQueryDescriptor =
                     this.QueryDescriptor.CreateCopy(true, true, false);

        this.ProductsSource.GetData
        (
            exportQueryDescriptor,
            (products) =>
            {
                PagedCollectionView current =
                                   this.Products as PagedCollectionView;
                PagedCollectionView exportedItems =
                                   new PagedCollectionView(products);                    

                exportedItems.CopyDefinitionsFrom(current, true,
                                   false, false, false);

                this.ExportItems = exportedItems;
            },
            (totalItemCount) =>
            {

            },
            (error) =>
            {

            }
        );
    }
}

Quite simple and straightforward, isn’t it? Also notice that the QueryDescriptor now has a CreateCopy, a new time-saving method that returns a clone based on the given source and options. The most important point here is the flexibility that UXGridView offered since it gives you full control over how the data retrieval is done in the ViewModel.

4 Built-in Exporting Data Format

UXGridView allows you to export the data source into four data format – not only one, or two. Users have the choice to export data to HTML, Excel, CSV or just a plain text file. From the user interface perspective, all you need to do is to set the CanUserExport property to true. A tiny, stylish dropdown button will then appear in the status bar, next to the data pager. The available data format is listed in the menu when the dropdown button is clicked, such as shown below.

Exporting user interface

Although the user interface has been well predefined, they are fully customized thanks to the loosely-coupled UI architecture. For instances, you can change the dropdown button to a more stylish callout, or just a plain command button if you preferred.

When the data exporting process completes, you’ll be prompted to save the results to your local computer. The following illustration shows the Excel spreadsheet that contains the exported results.

UXGridView data exported to Excel

UXGridView also offers a number of exporting options such as whether to include column footers, column headers or the group footers in the exported results. For even more fine-grained HTML results, you can customize the style of each generated row and cell output through the ExportCssStyleSelector, another big plus for MVVM implementation!

Style and Template Selectors

UXGridView implements a wealth of style selectors and template selectors, giving the freedom you need to create rich data presentation the way you want. The selector pattern is a first-class MVVM citizen that enables you to write custom logics in a separate class instead of in the view level. You get two benefits immediately: greater reusability and cleaner implementation due to the view/code separation.

One of the most common scenarios, for instances, is to show discontinued products in a different background color, allowing users to quickly distinguish the useful information they need to work with. The following illustration shows the results of a RowStyleSelector implementation.

RowStyleSelector in UXGridView

Another common scenario is to display different information based on specific conditions. For instances, showing a Reorder hyperlink button in the case that the products were out-of-stock. This can be done through an implementation of CellTemplateSelector, see the results below.

CellTemplateSelector in UXGridView

Or how about a more advanced scenario like applying a different background brush in the row header of each different group level? That’s also possible to be done through an implementation of RowGroupHeaderStyleSelector.

RowGroupHeaderStyleSelector in UXGridView

I hope the above illustrations give you a clear idea what the style and template selectors are all about.

To be more exact, UXGridView provides 13 selectors for the row, cell, column header, column footer and group elements. The complete list is as follows:

  • Row Style Selector
  • Row Template Selector
  • Cell Style Selector
  • Cell Template Selector
  • Column Header Style Selector
  • Column Header Template Selector
  • Column Footer Style
  • Column Footer Cell Style
  • Column Footer Cell Template
  • Row Details Template Selector
  • Row Group Header Style Selector
  • Row Group Footer Style
  • Row Group Footer Cell Style

Note that the above selectors have not included the selectors of other elements such as editing and exporting.

Multi Aggregates

Another nice addition in the RC release is the support for multiple aggregates in both the column footer and group footer. It will be definitely useful for line-of-business applications, particularly in financial extensive applications. So here the feature is when you need it.

Multi aggregates support in UXGridView

Custom Grouping

The RC release adds more powerful features allowing developers to fine-tuning the grouping results in UXGridView. While most competing grids used locked-down approaches, UXGridView is quite the opposite. You can now define your own custom groups by writing custom logics in a separate class which is then instantiated in the XAML and assigned to the GroupConverter property of the UXGridViewGroupDescriptor.

The sample in the following illustration groups the products data based on a range of CategoryID values.

Grouping with custom logic

Another popular scenario that can be achieved using the group converter is the value list capability where more meaningful information can be displayed in the group header instead of useless IDs, for instances, displaying the actual name of a category instead of the ID such as shown below.

Grouping with value list

Read-only Binding

Last but not least, among the top requested features is the read-only binding which we managed to ship in the RC release. With the read-only binding expression, you can write a custom logic that determines when a particular row or cell should be read-only (not editable).

UXGridView provides read-only binding at both the row and cell level. The read-only binding expression at row level, if returns true when evaluated, will supersede the read-only binding expression at the cell level. This means that if the read-only binding is specified at the row level and returns a true value, the entire row will no longer editable regardless of the value of the binding expression specified in the cells.

For  examples, consider a scenario where discontinued products should be not editable. In such case, the IsReadOnlyBinding of the UXGridView is bound to the Discontinued property of the product entity. To prevent users to accidentally uncheck the Discontinued value, the same property can be bind to the IsReadOnlyBinding of the UXGridViewColumn. The binding expression at the UXGridView level applies to the rows, while the one at the UXGridViewColumn applies to the cells.

Luckily, the RC release shipped with an example based on the above scenarios. The following illustration shows the discontinued product which can no longer be edited.

IsReadOnlyBinding in UXGridView

WCF RIA SP1 Support

The UXGridView, UXDataPager and UXDataFilter controls in the RC release have been updated to support the recently released WCF RIA SP1. Most notable is the paging support for new data model returned in the children of the navigator properties. The data controls are also backward compatible with the previous WCF RIA.

Download the RC Bits

UXGridView Release Candidate includes complete feature sets and near-RTM quality, which means that you can start using UXGridView to build amazingly rich data-centric applications for the Silverlight and WPF platforms. As you have learned through the series of technology preview releases, each UXGridView feature is uniquely engineered to work best for many MVVM scenarios, making it the industry’s first and most advanced MVVM-ready data grid for the Silverlight and WPF development.

To summarize, the RC release adds a host of exciting new and essential features such as data exporting, style and template selectors, multi aggregates, and much more. We’ve also added many new samples that demonstrate real-world development scenarios such as using different sort member for value list and displaying an image in the cells. The RTM version will add a couple “extra” features, so stay tuned for the next announcement!

Click here to download the RC bits and test-drive the new UXGridView features today. The download package includes latest ClientUI assemblies as well as updated and new samples for both Silverlight and WPF platforms.

Please note that the UXGridView RC is the last public community release. The next milestone would be the UXGridView RTM release together with dozens of new members in ClientUI 5. For now, we’d love to hear what you think about the new features and enhancements available in the RC. Please post your feedback, questions or issues to our community forum.

Best,
Jimmy
Chief Software Architect

UXGridView CTP2: MVVM Data Editing

Two weeks ago, we released the first CTP of our new data controls for Silverlight and WPF. The first CTP was focused on MVVM Grid architecture and server-based data access, as well as data operation such as paging and filtering. More information can be found here.

Today, I’m excited to announce the availability of the second CTP of our data controls. Our milestone in this release is strongly focused on data validation and data editing that supports MVVM design pattern. The release also includes a number of great features like batch update support for DevForce data service, native ValueList support for display and edit mode, customizable editing controls, and a host of UI/X tweaking.

Click here to download the CTP2, and read the details below to discover what’s new.

Data Validation & Editing with MVVM Pattern

For decades, developers have to write a bunch of code to implement an editable grid, from wiring editing events to writing validation code in a number of places. That’s even true for the latest built-in Silverlight DataGrid, for instances, you should write code to perform data validation in the RowEditEnded event. This pattern of development, unfortunately, makes your code difficult to test and maintain. And it definitely violates the MVVM pattern as the event wiring requires a strong reference to the view elements.

Unlike other Silverlight grids, UXGridView supports MVVM-style data editing out-of-the-box. It allows you to write data validation and editing logic entirely in the ViewModel without trading-off the rich editing features in the grid. The benefits of using MVVM in data editing applications are obvious – you can easily reuse, test and extend the interactions logics in the ViewModel without affecting the view or data access layers.

With UXGridView, you don’t wire events in order to perform data validation. While we still provided routed events as a mean to work with the Grid using the classic MVP pattern, it’s unnecessary to wire any editing events to perform editing operations such as begin, commit or cancel edit. Implementing data validation and editing using MVVM pattern is simple and straightforward. First, you create the delegate commands for each editing command in the ViewModel, then bind the commands to the UXGridView through data binding declaration.

The following illustration shows a simple MVVM implementation of data validation and editing in UXGridView.

ViewModel:

 public DelegateCommand DeleteRowCommand { get; set; }
 public DelegateCommand InsertRowCommand { get; set; }
 public DelegateCommand UpdateRowCommand { get; set; }
 public DelegateCommand ValidateRowCommand { get; set; }

 public void ExecuteValidateRow(object parameter)
 {
      this.EditableProductsSource.Validate(parameter);
 }

public void ExecutePrepareNewRow(object parameter)
{
    this.NewProduct = this.EditableProductsSource.Create();
    this.EditableProductsSource.Insert(this.NewProduct);
}

public void ExecuteDeleteRow(object parameter)
{
    this.EditableProductsSource.Delete(parameter as IList);
}

 ...

XAML Page:

 <Intersoft:UXGridView ItemsSource="{Binding Products}" 
              CanUserAdd="True" 
              CanUserDelete="True"
              CanUserEdit="True"
              SelectedItem="{Binding SelectedProduct, Mode=TwoWay}"
              ValidateRowCommand="{Binding ValidateRowCommand}"
              InsertRowCommand="{Binding InsertRowCommand}"
              DeleteRowCommand="{Binding DeleteRowCommand}"
              UpdateRowCommand="{Binding UpdateRowCommand}" />

As you can see from the above code snippet, the beautiful of the MVVM pattern is that you have full control over your business and interaction logic. For example, if you used a powerful data service like DevForce, you can simply delegate the call to a repository that automatically execute the validation to the given entity.

You really don’t need to worry about the change tracking, dirty state, or valid state – the UXGridView takes care of them automatically. For an instance, when the modified row contains validation errors, UXGridView will not allow you to commit the changes until you correct the error, or cancel the changes – see the screenshot below.

Intuitive row validation

In addition to the solid MVVM-ready editing architecture, UXGridView also sports great looking interface, which includes a handy error message displayed in the status bar, as well as error notification in the row and row header.

New Row & Delete

You asked for it, we deliver! The new UXGridView brings back the features you loved to use such as the “new row” interface for quick data adding, inline editing, and delete row support. While these features sound common in most ASP.NET grids, they aren’t in Silverlight, so we built one.

The "new row” interface works pretty much similar to the ASP.NET version of our flagship WebGrid. You click on the new row bar to begin adding new rows. Keyboard arrow keys are also fully supported for navigating to the new row.

New row interface

The other nice feature is the support for multiple selection and row delete. The multiple selection is enabled by default, so you can easily select multiple rows by using the combination of Ctrl and Shift keys. Once selected, press Delete to delete the selection.

Multiple selection

Batch Update Support for DevForce

If you noticed on the above screenshots close enough, chances are that you’ll spot two interesting buttons beside the pager control. Think you’ve seen these buttons before? Well, you must have seen it in the batch update feature we implemented in the ASP.NET version of our WebGrid.

If you haven’t heard much about batch update, it is a very powerful feature in data-aware applications which allows you to make multiple edits locally and submit them in a single round trip. Unfortunately, the batch update implementation in Silverlight is fairly challenging since the UXGridView control should not be tightly coupled to any data access strategy. This means that the batch update should be supported by the data service provider as well.

Luckily, DevForce from IdeaBlade includes full support for batch update, thanks to their client-side caching feature. The WCF RIA Services, on the other hands, has very limited support for batch update, you might notice the options to be disabled in several editing samples for RIA.

When the batch update feature is enabled, all changes you made in the UXGridView will be kept locally. Consequently, your implementation for the Insert, Update and Delete in the ViewModel is not required to call the Save method. This, and many other benefits, make batch update an ideal approach to your data intensive applications as data input becomes more responsive and faster with reduced server-client round trip.

The changes you made in the grid can be submitted to server in batch through the SaveChanges command; or rejected through the RejectChanges command. The UXGridView control provides default buttons in the status bar interface which execute these commands, see the illustration below.

Batch update commands

The SaveChanges and RejectChanges commands will be automatically disabled when they cannot execute. For instances, when the grid is busy, or when the grid has no more changes. Again, this process is controlled from your ViewModel through the binding to the HasChanges property in UXGridView.

You can also explore a bunch of editing behaviors implemented in the UXGridView. In the DevForce samples, you can try to use inline or batch update mode via the Options panel, see below.

Sample options

Customizable Editing Controls

Now that we’ve got MVVM-ready editing architecture covered, as well as the editing behaviors like the enter key action and edit mouse gesture, the CTP2 release also shipped with powerful editing architecture that you’ll definitely excited to see.

Unlike other grid controls that require you to write specific interface to properly work in editing mode, we introduced editing cell template that allows you to use any existing input controls as the editing control for that specific column.

One of my favorite features is the easy plug-in to use the advanced input controls we introduced in the previous release such as UXNumericUpDown, UXDateTimePicker, UXCurrencyEdit and UXSliderBar just to name a few. For an instance, the following code shows how to use the UXNumericUpDown control as the editing control for UnitsInStock column:

 <Intersoft:UXGridViewTextColumn Header="Units In Stock"
                                 Binding="{Binding UnitsInStock}">
     <Intersoft:UXGridViewTextColumn.CellEditingTemplate>
         <DataTemplate>
             <Intersoft:UXNumericUpDown Maximum="9999" 
                        Value="{Binding UnitsInStock, Mode=TwoWay}"/>
         </DataTemplate>
     </Intersoft:UXGridViewTextColumn.CellEditingTemplate>
 </Intersoft:UXGridViewTextColumn>

Using UXNumericUpDown as editing control

You can also use a more unique, non-textbox input control such as UXSliderBar, by simply defining the control in the CellEditingTemplate similar to the above example.

Using UXSliderBar as editing control

The release also includes many other exciting features such as native ValueList support on both cell and editing mode, column template, and editing template selector. More on these in the next post.

Download the CTP2 Bits

Click here to download the CTP2 and test-drive the new UXGridView features today. The download package includes latest ClientUI assemblies as well as updated and new samples for both Silverlight and WPF platforms.

Make sure you checked out the new samples shipped in this CTP2 release, see the red-highlighted sections below.

New samples

Enjoy the new CTP bits! In the next several posts, we will cover more code-level details and usages on the UXGridView related to the editing features, so stay tuned.

We’d love to hear what you think about the new features available in CTP2, please post your feedback, questions or issues to our community forum.

All the best,

Jimmy

UXGridView Part II: Data Access the MVVM-way with QueryDescriptor

As Jimmy wrote in his blog post, our upcoming Grid control for Silverlight and WPF, UXGridView, allows you to perform data operation with MVVM pattern elegantly using QueryDescriptor. In this post, I will explain some of fundamental concepts of the QueryDescriptor in more practical ways.

Understanding QueryDescriptor

First let’s take a look the QueryDescriptor class below.

QueryDescriptor Class

As you can see, the QueryDescriptor has three properties that hold the information about the query. It also has a QueryChanged event that will be raised when any of the QueryDescriptor’s properties are changed. The following illustration shows some examples on how query information is stored in the QueryDescriptor.

QueryDescriptor queryDescriptor = new QueryDescriptor();

// filtering
// get records that have 
// (UnitPrice >= 0 AND UnitPrice < 50) OR (UnitPrice == 0)
CompositeFilterDescriptorCollection groupFilter1 = 
    new CompositeFilterDescriptorCollection();

groupFilter1.LogicalOperator = FilterCompositionLogicalOperator.And;
groupFilter1.Add(
    new FilterDescriptor() 
    { 
        PropertyName = "UnitPrice", 
        Operator = FilterOperator.IsGreaterThanOrEqualTo, Value = 0 
    }
);
groupFilter1.Add(
    new FilterDescriptor() 
    { 
        PropertyName = "UnitPrice", 
        Operator = FilterOperator.IsLessThan, Value = 50 
    }
);

CompositeFilterDescriptorCollection groupFilter2 = 
    new CompositeFilterDescriptorCollection();

groupFilter2.LogicalOperator = FilterCompositionLogicalOperator.And;
groupFilter2.Add(
    new FilterDescriptor() 
    { 
        PropertyName = "UnitsInStock", 
        Operator = FilterOperator.IsEqualTo, Value = 0 
    }
);

queryDescriptor.FilterDescriptors.LogicalOperator = 
    FilterCompositionLogicalOperator.Or;

queryDescriptor.FilterDescriptors.Add(groupFilter1);
queryDescriptor.FilterDescriptors.Add(groupFilter2);

// paging
// get the record 6 - 10
queryDescriptor.PageDescriptor.PageSize = 5;
queryDescriptor.PageDescriptor.PageIndex = 1;

// sorting
// sort by category ascending then by product id descending
queryDescriptor.SortDescriptors.Add(
    new SortDescriptor() 
    { 
        PropertyName = "CategoryID", 
        Direction = System.ComponentModel.ListSortDirection.Ascending 
    }
);
queryDescriptor.SortDescriptors.Add(
    new SortDescriptor() 
    { 
        PropertyName = "ProductID", 
        Direction = System.ComponentModel.ListSortDirection.Descending 
    }
);    

With our data controls, the QueryDescriptor will be updated automatically whenever users perform data operations through our data controls such as paging, filtering and sorting. So all you need to do here is simply wiring up the QueryDescriptor to the data controls and listen to its QueryChanged event.

In the QueryChanged function delegate, you will need to parse the information in QueryDescriptor to a data operation command for your specific data source. Fortunately, our data provider libraries come with some methods allowing you to easily parse the QueryDescriptor into WCF RIA or DevForce data service.

Next, I will show you how to bind the QueryDescriptor to UXGridView, listen to its QueryChanged and perform the data operation.

Binding QueryDescriptor to UXGridView using MVVM Pattern

First, let’s create the ViewModel for our example.

using System.Collections.Specialized;
using Intersoft.Client.Data.ComponentModel;

namespace UXGridView.Samples.ViewModels
{
    public class ListProductsViewModel : ViewModelBase
    {
        public ListProductsViewModel()
        {
            this._queryDescriptor = new QueryDescriptor();
        }

        private INotifyCollectionChanged _products;
        private QueryDescriptor _queryDescriptor;

        public INotifyCollectionChanged Products
        {
            get { return this._products; }
            set
            {
                if (this._products != value)
                {
                    this._products = value;
                    this.OnPropertyChanged("Products");
                }
            }
        }

        public QueryDescriptor QueryDescriptor
        {
            get
            {
                return this._queryDescriptor;
            }
            set
            {
                if (this._queryDescriptor != value)
                {
                    if (this._queryDescriptor != null)
                        this._queryDescriptor.QueryChanged 
                            -= new System.EventHandler(OnQueryChanged);

                    this._queryDescriptor = value;
                    this._queryDescriptor.QueryChanged 
                        += new System.EventHandler(OnQueryChanged);

                    this.OnPropertyChanged("QueryDescriptor");
                }
            }
        }

        public virtual void LoadProducts()
        {

        }

        private void OnQueryChanged(object sender, System.EventArgs e)
        {
            this.LoadProducts();
        }
    }
}        

Notice that the LoadProducts() is still empty now, we’ll get to that later. Next we will bind this to our UXGridView in our View.

<Intersoft:UXPage
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	xmlns:Intersoft="http://intersoft.clientui.com/schemas"
        xmlns:ViewModels="clr-namespace:UXGridView.Samples.ViewModels"
	x:Class="UXGridView.Samples.Views.UXGridView.ListProducts"
	Title="ListProducts Page"
	d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot">
        <Grid.DataContext>
            <ViewModels:ListProductsViewModel/>
        </Grid.DataContext>

        <Grid MaxWidth="700" Margin="12">
            <Intersoft:UXGridView 
                Margin="8" AutoGenerateColumns="False" 
                ItemsSource="{Binding Products}"
                QueryOperation="Server"
                SortDescriptors="{Binding QueryDescriptor.SortDescriptors}"
                PageDescriptor="{Binding QueryDescriptor.PageDescriptor}" 
                PageSize="20" CanUserPage="True">
                <Intersoft:UXGridView.Columns>
                    <Intersoft:UXGridViewTextColumn 
                        Header="Category ID" 
                        Binding="{Binding CategoryID}"/>
                    <Intersoft:UXGridViewTextColumn 
                        Header="Product ID" 
                        Binding="{Binding ProductID}" 
                        Aggregate="Count" FooterFormatString="Count = {0}"/>
                    <Intersoft:UXGridViewTextColumn 
                        Header="Product Name" 
                        Binding="{Binding ProductName}"/>
                    <Intersoft:UXGridViewTextColumn 
                        Header="Unit Price" 
                        Binding="{Binding UnitPrice}" 
                        Aggregate="Avg" FooterFormatString="Avg = {0}"/>
                    <Intersoft:UXGridViewTextColumn 
                        Header="Units In Stock" 
                        Binding="{Binding UnitsInStock}" 
                        Aggregate="Max" FooterFormatString="Max = {0}"/>
                    <Intersoft:UXGridViewTextColumn 
                        Header="Units On Order" 
                        Binding="{Binding UnitsOnOrder}" 
                        Aggregate="Min" FooterFormatString="Min = {0}"/>
                    <Intersoft:UXGridViewTextColumn 
                        Header="Quantity Per Unit" 
                        Binding="{Binding QuantityPerUnit}"/>
                </Intersoft:UXGridView.Columns>
            </Intersoft:UXGridView>
        </Grid>
    </Grid>
</Intersoft:UXPage>

Note that you will need to set the QueryOperation to Server to enable server-side data operation. That’s required because UXGridView also has the capability to manipulate the data at client side, which is the default setting. For now, let’s focus on the server-side query mode.

The QueryChanged event of the QueryDescriptor will be raised when it is bind to any of our data controls such as UXGridView, UXDataFilter or UXDataPager. The event will also be raised whenever there are changes in the QueryDescriptor, so it is the only place where you want to handle all data operations.

Now, let’s start processing this QueryDescriptor and retrieve a piece of data from our repository.

Parsing QueryDescriptor and Retrieving Data from WCF RIA

To parse the QueryDescriptor to WCF RIA, you need to include the Intersoft.Client.Data.Provider.Ria assembly in your project. This data provider assembly provides several methods that will allow you to easily parse the QueryDescriptor to the WCF RIA data service.

Now, let’s parse our QueryDescriptor and write some code to load the data in the LoadProducts() method that we’ve prepared in the previous section.

private NorthwindDomainContext _manager;
private NorthwindDomainContext Manager
{
    get
    {
        if (this._manager == null)
            this._manager = new NorthwindDomainContext();

        return this._manager;
    }
}

public virtual void LoadProducts()
{
    if (Intersoft.Client.Framework.ISControl.IsInDesignModeStatic)
        return;


    var query = this.Manager.GetProductsQuery()
                         .OrderBy(p => p.ProductID)
                         .Parse(this.QueryDescriptor);
    query.IncludeTotalCount = true;


    this.Manager.Load(
        query,
        op =>
        {
            if (op.IsComplete)
            {
                this.Products = new PagedCollectionView(op.Entities);
                if (op.TotalEntityCount != -1)
                    this.QueryDescriptor.PageDescriptor.TotalItemCount 
                        = op.TotalEntityCount;
            }
            else
            {
                // error handling
            }
        },

        true);
}

private void OnQueryChanged(object sender, System.EventArgs e)
{
    this.LoadProducts();
}
        

As you can see, the implementation is very straightforward, you just need to call .Parse(this.QueryDescriptor) to produce a query that WCF RIA can process. Note that IncludeTotalCount is set to True, which is important in paging scenarios as we will need to set the QueryDescriptor.PageDescriptor.TotalItemCount property to the total entity count of the particular query. This enables the data pager UI to determine the total number of pages available.

Parsing QueryDescriptor and Retrieving Data from Dev Force

In addition to the WCF RIA, you can also parse the QueryDescriptor to a DevForce service using similar approaches, with minor adjustments. First, you need to include the Intersoft.Client.Data.Provider.DevForce assembly in your project. This data provider provides similar methods as available in the RIA counterpart. Next, you need to adjust some of the code such as declaring the relavant DevForce type, see below.

private NorthwindEntities _manager;
private NorthwindEntities Manager
{
    get
    {
        if (this._manager == null)
            this._manager = new NorthwindEntities();

        return this._manager;
    }
}

public virtual void LoadProducts()
{
    if (Intersoft.Client.Framework.ISControl.IsInDesignModeStatic)
        return;

    this.Manager.Products
        .OrderBy(p => p.ProductID).Parse(this.QueryDescriptor)
        .ExecuteAsync(
        op =>
        {
            if (op.CompletedSuccessfully)
            {
                this.Products = new PagedCollectionView(op.Results);
            }
            else
            {
                // error handling
            }
        }
        );                 
}

public virtual void GetTotalItemCount()
{
    var queryCount = this.Manager.Products
        .Parse(this.QueryDescriptor, false).AsScalarAsync().Count();

    queryCount.Completed += (o, e) =>
    {
        if (e.Result != -1)
            this.QueryDescriptor.PageDescriptor.TotalItemCount = 
                e.Result;
    };    
}

private void OnQueryChanged(object sender, System.EventArgs e)
{
    this.GetTotalItemCount();
    this.LoadProducts();
}

Notice that you need to retrieve the total item count in two separate calls. This is required since DevForce handles the total item count retrieval differently.

I hope you agree that the QueryDescriptor makes MVVM and data service significantly easier and straightforward to implement. Also, remember that the QueryDescriptor can be shared across multiple controls such as UXDataFilter and UXDataPager, in addition to the UXGridView.

In my next post, I will cover about some nice Grid features that we shipped in the first CTP release. For now, download the CTP1 bits here, and enjoy building your data-centric application the MVVM way.

Best Regards,

Andry

Introducing UXGridView: The MVVM-ready Grid for Silverlight and WPF

A while back, I posted a blog that describes our plan to release a new Grid control to join our flagship ClientUI suite. One of the key goals of the new Grid control is to provide a full MVVM-ready data grid implementation that supports our long-term vision in cross-platform lineups, particularly for the Silverlight and WPF platforms.

The new Grid control, named UXGridView, will also be “LoB centric”, which means many of its features will be focused on line-of-business scenarios and usage, such as support for server paging and filtering through loosely-coupled MVVM pattern and data providers, grouping and totaling, and data exporting to name a few.

In this first series of the UXGridView blogs, I’m excited to introduce the first public preview of our most anticipated data controls. The first CTP release includes UXGridView, UXDataPager and UXDataFilter. Both Silverlight and WPF versions are available. Let’s see what they have to offer.

MVVM & Data Service Made Easy

Data access in Silverlight and WPF has always been a challenging task, particularly when it comes to a combination of server-based operations like server filtering and paging. Put it together with another two design goals, MVVM pattern and unified cross-platform API, you will be surprised no one had ever addressed this elegantly, yet. As the matter of fact, I’ve tried to goggle this myself for a few hours without any luck.

Simplifying data access with our UI lineups has always been the utmost priority and motivation in our products engineering. This is reflected in our new data control lineups – the UXGridView, UXDataPager and UXDataFilter – which targeted to run in both Silverlight and WPF platforms; including support for server operations without coupled to any data access strategy.

UXGridView makes MVVM-compliant server operations possible through QueryDescriptor, a simple CLR object that developers can consume in their ViewModel classes. The QueryDescriptor contains information about the query which are two-way bound to the View components such as data grid, pager and filter. The descriptor is then parsed to the data provider, resulting the data shape to be processed further in the ViewModel. The interesting part here is that the View doesn’t know the existence of the descriptor, nor the other way around. And more importantly, the descriptor is not coupled to any data access strategy, which means you can parse it yourself in the way that meaningful to you, or let our extensions did it for you. More on that soon.

Let’s take a look at the following illustration for a big picture on the architectural design around the QueryDescriptor, MVVM and the data controls.

ClientUI Data Framework & QueryDescriptor

As seen in the above illustration, the ViewModel does all the works, from parsing the descriptor, perform the query asynchronously, to setting the result into the collection property. The View simply accepts whatever data the ViewModel provided through two-way binding, and is completely agnostic to the operations or objects used in the ViewModel.

It’s important to note that the QueryDescriptor and its related classes are implemented in a lightweight assembly called Intersoft.Client.Data.ComponentModel, makes it ideal for use within your Model or ViewModel. This assembly contains only simple CLR objects – strictly no View/UI stuff.

In the high level implementation, the data view controls are declared in the following XAML example.

<Intersoft:UXGridView QueryOperation="Server"
                      IsBusy="{Binding IsBusy}"
                      ItemsSource="{Binding Products}" 
                      SortDescriptors="{Binding QueryDescriptor.
                               SortDescriptors, Mode=TwoWay}"/>

<Intersoft:UXDataFilter ItemsSource="{Binding Categories}"
                        QueryOperation="Server"
                        FilterDescriptors="{Binding QueryDescriptor.
                                FilterDescriptors, Mode=TwoWay}"/>

<Intersoft:UXDataPager PageSize="20" QueryOperation="Server"
                       PageDescriptor="{Binding QueryDescriptor.
                                PageDescriptor}"/>

Next, you create a new instance of the QueryDescriptor in the ViewModel. The descriptor is a simple CLR property that is no difference with other properties in the ViewModel, such as shown below.

private QueryDescriptor _queryDescriptor;

public QueryDescriptor QueryDescriptor
{
    get
    {
        return this._queryDescriptor;
    }
    set
    {
        if (this._queryDescriptor != value)
        {
            if (this._queryDescriptor != null)
                this._queryDescriptor.QueryChanged -= 
                   new System.EventHandler(OnQueryChanged);

            this._queryDescriptor = value;
            this._queryDescriptor.QueryChanged += 
                new System.EventHandler(OnQueryChanged);

            this.OnPropertyChanged("QueryDescriptor");
        }
    }
}

public DefaultViewModel()
{
      this.QueryDescriptor = new QueryDescriptor();
}

Clearly, any changes that users made at runtime, such as sorting on the UXGridView, navigating to certain page on the UXDataPager, or applying filter on the UXDataFilter; automatically raises the QueryChanged event of the descriptor. Since the descriptor contains all information about the requested query, it allows you to centralize all data operations in a single entry point in your ViewModel, such as shown below.

private void OnQueryChanged(object sender, EventArgs e)
{
      this.LoadProducts();
}

Hopefully I have shown it clear to you how easy it is to create a high-performance data grid with server filtering and server paging. And with MVVM pattern, it allows you to consistently apply the same technique to the rest of grids in your applications.

Intersoft Data Extension for DevForce 6.0.8

For DevForce’s users, get ready to query your data in a whole new light! In this first CTP release, we’re excited to ship the data provider extension that makes it extremely easy to query data using DevForce 6.0.8. The data provider extension takes the QueryDescriptor as an input, parses it, and automatically translates it into something that DevForce understood.

This means that all server-based data operations, such as sorting, filtering and paging, are taken care in a single syntax, see the following code.

public virtual void LoadProducts()
{
    this.IsBusy = true;

    this.ProductsSource.GetData
    (
        this.QueryDescriptor,

        (products) =>
        {
            this.Products = new PagedCollectionView(products);
            this.IsBusy = false;
        },
        (error) =>
        {
	    // handle error
        }
    );
}

Again, remember that the data extension is not coupled to the descriptor nor the data controls. It’s implemented in a separate lightweight assembly that establishes a reference to both Intersoft.Client.Data.ComponentModel and DevForce assemblies.

Update 2/15/2010: Our friend, Bill Gower, posted a series of great tutorials explaining how to use QueryDescriptor and UXGridView in real-world scenarios. Check out his thought on UXGridView here, the basics of QueryDescriptor here, and how to configure multiple FilterDescriptors here.

Download the CTP1 Bits

The first CTP bits released today includes a handful of samples that you can play around to test drive the core Grid features. The sample project comes with a simple navigation interface, built entirely with ClientUI’s navigation framework, shown below.

UXGridView Samples

Click here to download the CTP1 bits of the new data controls. This single download includes a number of solutions tailored for different platforms and different data access provider. The download contains the following:

  • Latest ClientUI assemblies (Framework, Aqua, Interactivity)
  • ClientUI Data CTP1 assemblies (Silverlight and WPF)
  • Sample solution using WCF RIA Services (Silverlight)
  • Sample solution using DevForce 6.0.8 (Silverlight and WPF)

All solutions share the same XAML file despite the differences in platforms and data access technologies – another interesting sample project to learn about MVVM and unified development model, see the following screenshot.

Solution files

We’d love to hear what you think about our new data controls. Be sure to send your thoughts to feedback@intersoftpt.com. And before you asked for a feature, please check out the CTP milestones in the last section below.

IMPORTANT: You are required to install ClientUI in your development machine to develop and run the sample solutions. Click here to download the ClientUI free trial. The latest DevForce (6.0.8) is required to run the DevForce samples, which can be obtained here.

CTP Milestones

Last but not least, I’d like to share about our release plans with you. Instead of releasing huge feature-sets in fairly longer timespan, we’ve chosen to release the UXGridView bits in more iterations with shorter timespan, focusing on each core feature-set at a time. This also allows our valued customers and partners to get an early preview, and send feedback while the product is being baked.

The UXGridView will be released in three CTPs before it reaches its RTM release scheduled on March this year. See the following chart for the milestone details.

UXGridView Milestones

In summary, the first CTP release is highly focused on the following feature sets:

  • Core UXGridView infrastructure, including MVVM-ready design.
  • Core UXGridView features:
    • Layout features, such as dynamic row height, column freezing.
    • Interaction features, such as column resizing, reordering, fluid drag-drop.
    • Data features like group totals and aggregates.
    • UI features, such as status bar, commands, busy management.
    • Performance features, allows you to display millions of rows without lagging.
  • Core data infrastructure, supporting both client-side and server-side query operation.
  • Core platform infrastructure, supporting both Silverlight and WPF.
  • Data component model, including QueryDescriptor and related data model.
  • Data providers:
    • For WCF RIA Services (Silverlight only, RIA did not support WPF)
    • For DevForce (Silverlight and WPF)
  • UXDataPager with MVVM-ready architecture leveraging commands, visual state and multi-binding for loosely-coupled UI engineering. This allows you to completely customize the pager user interface without affecting the behaviors.
  • UXDataFilter with binding and core features, more UI stuff to come.

Enjoy the CTP bits, and stay tuned for more exciting details!

PS: UXGridView is fully supported starting from this CTP release. Please post your questions or issues to our community forum.

All the best,

Jimmy Petrus

Chief Software Architect

Create a Rich Silverlight Message Board using MVVM Pattern and WCF RIA Services

In the past several months, I’ve been actively blogging about our next-generation user interface library for the Silverlight and WPF development, which has just been RTM-ed three weeks ago. I hope you’ve enjoyed playing around with the new controls and exciting features that we delivered. In case you haven’t got your copy, click here to get started.

While we’ve shipped hundreds of great samples that you can learn, or experience directly online, you may have realized there wasn’t a single blog post yet that guides you through creating basic Silverlight application using the ClientUI controls from front-to-back. The reason for that is because we’re still in progress preparing a comprehensive set of learning resources for you. Eventually we will have around 40-50 new videos, walkthroughs, and how-to articles available by the next week or two at the latest. So, stay tuned for our announcement in this blog site.

Not too long after I posted my blog about Top 10 Must-See Samples last week, I received several emails from customers that asked for a quick walkthrough to use the ClientUI controls in a real-world scenario, that is, retrieving data from the server-side database via WCF RIA Services and apply MVVM pattern on the top of that!

At the same time, we were migrating the message board from an earlier version of our Silverlight demo (known as Sirius which is now discontinued and completely replaced with the new ClientUI Showcase) to the new ClientUI library. The new message board happened to use the MVVM pattern, and it connects to the database via WCF RIA Services too. Just perfect, that’s an ideal topic to be blogged about!

In this blog post, I will share the key techniques that we used to build a richer Silverlight message board using the ClientUI library. Instead of writing a lengthy walkthrough from the ground zero, this blog post will be more focused on the key challenges and common obstacles found while building rich user interface using MVVM pattern in the combination with WCF RIA Services, Entity Framework and Domain Service. So, to effectively follow this post, you’re required to have basic understanding in the MVVM pattern and WCF RIA Services at the minimum. To learn more about MVVM pattern, read my previous post MVVM Framework in Silverlight.

Setting The Goal

Before we delved deeper into the project discussion, it’s important to set the preliminary goals and objectives of the project – outlining the general features, modules, presentation pattern, data access and connectivity and the application pattern.

The message board project that we want to achieve using ClientUI was planned to have the following objectives:

  • An elegant and clean user interface that emphasizes on ease-of-use and appealing experience.
  • High performance and responsive UI. Load only initial chunk of data at first load, then allow users to load more data on demand.
  • Customizable layout and appearance that is completely data-driven. I.e, callout style corresponds to the color that user selects.
  • Data access and connectivity to server-side SQL database through WCF RIA Services.
  • Use MVVM pattern for rapid and consistent application development.
  • Use Entity Framework and Domain Service for data query and operation.

The following illustration shows the user interface and basic message board functionality that we want to achieve in this project.

Rich Silverlight Message Board Objectives

Project Overview

Our Silverlight message board project is consisted of two projects. The first is a Silverlight project that contains all the Silverlight assets, such as XAML, styles, converters, view models, and more. See the following illustration.

Silverlight Project

Some base classes such as the ModelBase, ViewModelBase and many of the ViewModels are already provided by the templates shipped in the ClientUI, thus makes it easier and faster for you to get started and work on the MVVM classes. This message board project itself is based on the Intersoft ClientUI MVVM Application Project Template.

The other project is an ASP.NET Web Application project that contains server-side business object, entity framework, and data access layer to access the SQL database. The Web project is also used to host the Silverlight application which typically delivered in the form of XAP. See the following illustration.

ASP.NET Web Project

UI (View) Challenges

One of the biggest advantages of modern client development – such as the Silverlight or WPF – is that it enables a complete separation on the application engineering process. Our team of designers and developers firstly agreed on the main layout, structure and the navigation part of the project – and then each division can work on the project in parallel, which means that designers can go on creating the styles and assets, while developers can go ahead with the codes, MVVM and other business requirements.

Many Silverlight projects that we built recently were significantly accelerated with the efficient collaboration process. Take this message board project as an example. When the designer team delivers the style assets, the overall UI can be dramatically transformed, from plain white to stunning wooden-warm look and feel, while did not affect any of the application features and behaviors being worked by the developers.

In this post, I won’t be covering the styling and beautifying process of the project. Let’s focus on the technical difficulties in the UI (View) part.

Building the Feedback Items List

In most app dev, you typically start with the data presentation part. In Silverlight, there are a number of presentation patterns that you can use to display a list of data, such as grid view, list box, items control and more. The items control is the most ideal presentation for this project as we wanted to show the list of messages in nicely arranged callouts which doesn’t require selection or other advanced features.

Using the user interface library that we have in ClientUI, we can quickly achieve our goal to display the feedback list using an UXItemsControl that contains a list of callouts. The ItemsPanel of the UXItemsControl can be flexibly changed to WrapPanel to provide automatic wrapping layout.

The implementation is quite straightforward, see the following XAML code snippet.

<Intersoft:UXScrollViewer VerticalScrollBarVisibility="Auto">
        <Grid>
                 <Intersoft:UXItemsControl HorizontalAlignment="Center" MaxWidth="1024"
                                           ItemsSource="{Binding Path=Feedbacks}">
                          <Intersoft:UXItemsControl.ItemsPanel>
                               <ItemsPanelTemplate>
                                     <Intersoft:WrapPanel/>
                               </ItemsPanelTemplate>
                        </Intersoft:UXItemsControl.ItemsPanel>
                          <Intersoft:UXItemsControl.ItemTemplate>
                              <StackPanel HorizontalAlignment="Center">
                                     <Intersoft:CallOut>
                                             <TextBlock Text="{Binding Quote}"/>
                                     </Intersoft:CallOut>
                                     <TextBlock Name="IdentityText">
                                           <Run Text="{Binding DisplayName}"/>
                                           <LineBreak/><Run Text="{Binding Title}"/>
                                     </TextBlock>
                              </StackPanel>
                        </Intersoft:UXItemsControl.ItemTemplate>
                 </Intersoft:UXItemsControl>
        </Grid>
</Intersoft:UXScrollViewer>

Now we’ve got the feedback items listed in plain callout that arranged using wrapping layout.

Using ItemTemplateSelector to Set Template Based on Data

Our next objective is to customize the callout style based on the color that user selected when posting a message. In ASP.NET, this process is normally handled in the codes by handling the OnDataBound or InitializeRow event, then check against the data and then set the desired properties or styles accordingly.

That’s not the case in WPF or Silverlight. Our approach would be using WPF-style data binding technique where the actual templating can be entirely defined in the XAML. Thanks to all our items control lineups, we provide the ItemTemplateSelector and ItemContainerStyleSelector to address this challenges elegantly. This also complies with the MVVM pattern where separation of concern is prioritized.

As the name implies, the ItemTemplateSelector enables the items control to select which item template to use based on the condition evaluated in the DataTemplateSelector class. We can create our own class that implement DataTemplateSelector class, and then overrides the SelectTemplate method to provide our own logic to determine the item template selection process.

The following C# code snippet shows the CalloutTemplateSelector class to process the callout template selection based on the data.

[ContentProperty("CalloutTemplates")]
public class CalloutTemplateSelector : DataTemplateSelector
{
    public CalloutTemplates CalloutTemplates { get; set; }

    public CalloutTemplateSelector()
    {
        this.CalloutTemplates = new CalloutTemplates();
    }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        Feedback data = item as Feedback;
        CalloutItemTemplate template =
                               this.CalloutTemplates.SingleOrDefault(
                                     c => c.Color.ToLower() == data.FavoriteColor.ToLower());

        if (template == null)
            template = this.CalloutTemplates[0];

        return template.Template;
    }
}

The following XAML code snippet shows the ItemTemplateSelector implementation that uses the CalloutTemplateSelector class shown above to display different style of callout according to the data.

<Intersoft:UXItemsControl ItemsSource="{Binding Path=Feedbacks}">
          ...
          <Intersoft:UXItemsControl.ItemTemplateSelector>
                  <local:CalloutTemplateSelector>
                         <local:CalloutItemTemplate Color="Natural" Template="{StaticResource Callout_Natural}"/>
                         <local:CalloutItemTemplate Color="Wood" Template="{StaticResource Callout_Wood}"/>
                         <local:CalloutItemTemplate Color="DarkBrown" Template="{StaticResource Callout_DarkBrown}"/>
                         <local:CalloutItemTemplate Color="Black" Template="{StaticResource Callout_Black}"/>
                  </local:CalloutTemplateSelector>
          </Intersoft:UXItemsControl.ItemTemplateSelector>
         ...
</Intersoft:UXItemsControl>

The ItemTemplateSelector and ItemContainerStyleSelector are two of the most commonly used data binding techniques in WPF – which we bring to the Silverlight platform through ClientUI.

Setting the Callout Pointer Target

Since we’re using a nice Callout shape to represent a message in this project, we quickly realize that we wanted to show the callout pointer to target the user name element beneath it.

As you can see the “red lines” in the following illustration, each message has different pointer target location since each message has different length based on the text that users provide.

Callout Pointer

Although our UXCallout has complete customization over the pointer location – such as the PointerOffset, PointerPoint1, etc – it could be a tedious task to calculate the pointer offset manually. Furthermore, the manual calculation won’t be a perfect solution as we aren’t allowed to access the “UI element” from within the view model.

Fortunately, our UXCallout is equipped with a nice feature called TargetElement. By simply setting the TargetElement to the desired element, the pointer of the Callout will be automatically pointing to the center offset of the specified target element. And since TargetElement is a dependency property, that means you can easily specify it in your template or binding.

To achieve our UI objective such as shown in the above illustration, we can set the TargetElement of our callout to target the user name element through Binding. See the following XAML code snippet.

...
 <Intersoft:CallOut Style="{StaticResource CalloutStyle}"
                    Background="{StaticResource DarkBrownGradient}"
                    BorderBrush="{StaticResource DarkBrownBorder}"
                    TargetElement="{Binding ElementName=IdentityText}" Foreground="White">
                    ...
</Intersoft:CallOut>
<TextBlock Name="IdentityText" Style="{StaticResource IdentityStyle}">
...

So far, we’ve addressed numerous key challenges related to the UI (View). Although we haven’t covered all view issues entirely in this topic, you should get sufficient ideas on how to solve the other UI challenges using similar pattern.

MVVM Challenges

As we’re building the project to be entirely based on the MVVM pattern, it becomes obvious that most challenges and issues would arise as you designed the user experiences for your application.

In this project, two of the major MVVM challenges are: calling asynchronous data retrieval from within the view model and how to deal with the view model separation for the “New Post”.

The following illustration shows the view models required in this project.

ViewModels Overview

As seen in the above illustration, the message board project is mainly comprised of two view models, named FeedbackListViewModel and NewFeedbackViewModel.

The FeedbackListViewModel Overview

The FeedbackListViewModel encapsulates the logic for the feedback list, such as retrieving the feedback list, getting the total count of the feedback, loading more feedback and managing the busy state for the data operation.

The following illustration shows the overview of FeedbackListViewModel.

FeedbackListViewModel Overview

Binding the Feedback List to View Model

The data binding for the items control to the view model is quite straightforward. It can be achieved by defining the Binding expression to the Feedbacks property available in the view model. The FeedbackListViewModel itself is defined directly as the DataContext of the UXPage in the XAML.

The following code shows how the feedback view model and the items source is defined. When the data context is set, it will automatically become available to the children in the tree. That enables the UXItemsControl to be notified with the available data context, then take its Feedbacks collection as the items source.

<Intersoft:UXPage>
     ...
    <Intersoft:UXPage.DataContext>
        <ViewModels:FeedbackListViewModel/>
    </Intersoft:UXPage.DataContext>
     ...

     <Intersoft:UXItemsControl ItemsSource="{Binding Path=Feedbacks}" />
</Intersoft:UXPage>

Load More Command

In the main view, we loaded only a chunk of initial records for highly responsive user experience. When you scroll down to the bottom edge of the list, you’ll notice the Load More Data button. This button will remain enabled when there’s more data to be loaded. To achieve this function, we’ll define the DelegateCommand in the view model, and then bind it to the hyperlink button through Command property.

The DelegateCommand, which is available in ClientUI Framework library, exposes CanExecute and Executed delegate which can be easily defined in the view model. The CanExecute result, interestingly, will automatically reflect the user interface elements that bound to it. In this case, the CanExecute result will automatically disable or enable the Load More button. This is an ideal solution for the MVVM pattern, all we need to do is to define the condition when the command can be executed, and the actual logic that will be processed when executed.

The following C# code shows the DelegateCommand initialization and the methods that handle its CanExecute and Executed delegate.

public FeedbackListViewModel()
{
      LoadMoreCommand = new DelegateCommand(ExecuteLoadMore, CanLoadMore);
}

private bool CanLoadMore(object parameter)
{
      return (this.LoadedPage < this.TotalPages);
}

private void ExecuteLoadMore(object parameter)
{
      LoadFeedback();
}

The following code shows how the delegate command is bound to the hyperlink button in the XAML.

<Intersoft:UXHyperlinkButton VerticalAlignment="Bottom" IsToggleButton="False"
                             Command="{Binding LoadMoreCommand}"
                             CommandCannotExecute="Collapsed">

            ...

</Intersoft:UXHyperlinkButton>

Managing Busy State

In my previous blog post, I’ve briefly discussed about the busy management support in certain ClientUI controls, specifically in the navigation frame and page.

The busy state management is particularly useful in this project as we’re retrieving data from the server asynchronously. Fortunately, ClientUI already include built-in features to manage the busy state directly in the navigation frame level. This eliminates the needs to define busy indicator in every page which could be a tedious task.

The busy state management feature in navigation frame is beyond the “classic” busy indicator. In addition to showing the “busy” indicator, it will also block the entire screen from user interaction. Furthermore, all commands-nature elements such as hyperlinks and buttons, will be automatically disabled to prevent users to inadvertently execute the command. See the following illustration to get a clearer picture.

Busy State Management

Now, let’s take a look how we can elegantly implement the feature in the view model to comply with our MVVM pattern architecture.

First, we define a property named IsBusy in the view model such as shown below:

public bool IsBusy
{
     get
     {
         return _isBusy;
     }
     set
     {
         if (_isBusy != value)
         {
             _isBusy = value;
             OnPropertyChanged("IsBusy");
         }
     }
 }

Second, we can bind this property to the IsBusy property available in the UXPage. This property automatically notifies the navigation frame that hosted it to manage the busy state according to the given value.

<Intersoft:UXPage
    Title="ClientUI Message Board"
    BlockUIOnBusy="True"
    IsBusy="{Binding IsBusy}">
   ...
</Intersoft.UXPage>

Note that the UXPage has BlockUIOnBusy property, which indicates whether the UI (User Interface) should be blocked when IsBusy is true.

Finally, we can now easily control the busy state from by simply setting the IsBusy property in the view model. The following code snippet shows an example that sets the busy state when retrieving data.

private void LoadFeedback()
{
    // Indicates that the view model is processing something
    // It will automatically reflect the state in the UI (View)
    IsBusy = true;

    _context.Load(_context.GetFeedbacksQuery(this.LoadedPage + 1),
                    (o) =>
                    {
                        if (o.IsComplete)
                        {
                            ...
                            // Sets the state back to normal
                            IsBusy = false;
                        }
                    }
                , true);
}

Pretty cool, isn’t it? Feel free to let me know if you’ve feedback or found other ways to implement the busy state management in your apps.

Showing the Status Window

When a data operation is completed, it’s nice to show a quick status that lets users aware of the request status. In this project, we’re going to use a lightweight window such as UXWindowChrome to show the status.

The challenge here is how we can efficiently control the status window (UI element) from the view model. There are a number of ways to implement this.

First, if you want to control the status window from within view model, you can dedicate a status window for each operation, then bind its IsClientVisible to your view model to control its visibility.

In our case, we would like to have only one instance of status window which is reused for multiple data operations, such as retrieving data, add new, and so on. In such scenario, the best practice is to handle this in the UI (View) level because all operations are mostly UI-related.

The good thing with this approach is that it shows the benefits of the view model that implements INotifyPropertyChanged which can be useful in a number of scenarios. Let’s take a look at the following example.

 // Executes when the user navigates to this page.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    // We can easily access to the view model from view through the DataContext
    FeedbackListViewModel viewModel = this.DataContext as FeedbackListViewModel;

    // Handle the view model's PropertyChanged 
    // Remember to detach it in OnNavigatingFrom override to avoid memory leak.
    viewModel.PropertyChanged += new PropertyChangedEventHandler(ViewModel_PropertyChanged);
}

private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    FeedbackListViewModel viewModel = this.DataContext as FeedbackListViewModel;

    if (e.PropertyName == "LoadedPage")
    {
          if (viewModel.LoadedPage > 1)
          {
               // Set the required status, i.e, the label text and visibility. 
               this.StatusLabel.Text = "10 more posts loaded";
               this.StatusWindow.IsClientVisible = true;
               // Hide the status after 2 seconds. 
               Utility.ExecuteTimeOut(2,
                        () =>
                        {
                            this.StatusWindow.IsClientVisible = false;
                        });
          }
    }
}

Here’s what the result looks like:

Showing Status Window

The NewFeedbackViewModel Overview

The NewFeedbackViewModel implementation is unique in a way that it is actually a children UI control that reside in the FeedbackList page. To enable the Callout and its entire children to use a different view model, we can set the DataContext of the Callout to the NewFeedbackViewModel which can be directly defined in the XAML code.

See the following illustration for the view model overview.

NewFeedbackViewModel Overview

Showing the Callout in View Model

One of the most challenging difficulties in MVVM is how a modern user interface such as callout can be efficiently managed using the MVVM pattern. In this project, we’re using the UXCallout control to display an iPad-style ‘Pop Over’, allowing users to conveniently write a new message in compelling user experience.

Since the UXCallout is built using the ClientUI’s popup architecture that complies with ISO-standards in usability, we can easily control its visibility through the IsOpen property.

The following code shows how the two-way binding is done.

<Intersoft:UXCallOut x:Name="Write_Callout" HorizontalAlignment="Right" Width="0"
                     PreferredPosition="Bottom"
                     IsOpen="{Binding IsAdding, Mode=TwoWay}">
                     ...
</Intersoft:UXCallOut>

While we’re now able to control the UXCallout’s visibility from the view model, the state is not synchronized with the “Write” button. Fortunately, all button lineups in ClientUI include toggle functionality. This way, we can make the button to use toggle behavior and bind its IsChecked to the IsOpen of the UXCallout using two-way binding.

See the code snippet below that shows the XAML definition for the toolbar button.

<Intersoft:UXToolBarButton x:Name="Button_Write" Content="Write"
                           IsToggleButton="True"
                           IsChecked="{Binding IsOpen, ElementName=Write_Callout, Mode=TwoWay}"
                           IsCheckedChanged="Button_Write_IsCheckedChanged"
                           ...
                           />

Binding the Input Controls

Next, the input controls can be bound directly to the Feedback entity which we have defined in the view model. This process is quite basic and straightforward as we’ve covered it in previous posts.

The following XAML code shows the input controls binding.

<Intersoft:UXItemsControl CornerRadius="4" ItemContainerStyle="{StaticResource CalloutInputStyle}">

           <Intersoft:UXTextBox x:Name="Quote_Input" Height="80" WatermarkText="What do you think about ClientUI?"
                                Text="{Binding Feedback.Quote, Mode=TwoWay}" AcceptsReturn="True"
                                VerticalScrollBarVisibility="Auto" />
           <Intersoft:UXTextBox x:Name="Name_Input" WatermarkText="Your name"
                                Text="{Binding Feedback.Name, Mode=TwoWay, ValidatesOnDataErrors=True}"
                                Intersoft:DataBinding.ClearErrorOnTextInput="True"/>
               ...
</Intersoft:UXItemsControl>

Using CommandParameter in Radio Button

One of the interesting scenarios in the UI for the new form is how we can design the user interface that allows users to select their preferred color. In our previous demo, this is done using view logic since the MVVM pattern has not existed yet at that time.

In this project, we’re migrating the color selection from the non-standard controls to button controls. The radio button is the most ideal user interface to achieve this objective.

However, since radio button is not a selection control, we can’t easily manage the selection in the same way as in UXListBox. Fortunately,we have the full-blown Commanding support in all button lineups. You got the idea, we can bind the radio button to a delegate command, then assign the CommandParameter in each radio button to be passed in the delegate command.

The following XAML snippet code shows how the binding is done in XAML.

<Intersoft:UXItemsControl Orientation="Horizontal" ItemContainerStyle="{StaticResource ColorSelectionStyle}">
           <Intersoft:UXRadioButton Background="#FFD9D9D9" ToolTipService.ToolTip="Silver"
                      Command="{Binding SelectColorCommand}" CommandParameter="Silver"/>
           <Intersoft:UXRadioButton Name="NaturalColor_Input"  Background="#FFFDE6B8" ToolTipService.ToolTip="Natural"
                      Command="{Binding SelectColorCommand}" CommandParameter="Natural"/>
          ...
</Intersoft:UXItemsControl>

And the corresponding view model code in C# here.

public NewFeedbackViewModel()
{
      this.SelectColorCommand = new DelegateCommand(ExecuteSelectColorCommand);
            ...
}

private void ExecuteSelectColorCommand(object parameter)
{
      this.Feedback.FavoriteColor = parameter.ToString();
}

As you become more familiar and fond with the MVVM pattern, you would be able to easily address numerous UI challenges in consistent manner. It also helps you to maintain the codes clean, readable and easy to extend.

Submitting Changes via Domain Context in View Model

Once we’re done with the UI, MVVM and binding, the final step is to perform the real database changes when the “Post” button is clicked. Again, this is done using the same MVVM pattern through Commanding.

Since the logic and data operation is encapsulated in the view model, we did not use the declarative DomainDataSource like in the old demo. Instead, the operation is called in the view model level through method call that automatically generated from the WCF domain service.

Consequently, the domain context is created only once at the FeedbackListViewModel level, which can be easily referenced through ParentViewModel in the NewFeedbackViewModel. This enables the new record operation to use the same domain context, which properly maintains the current state of the loaded data.

The following code snippet shows how the data operation is implemented.

private void ExecuteSaveCommand(object parameter)
{
        if (ValidateInput())
        {
                // set busy to block user interaction
                this.ParentViewModel.IsBusy = true;
                this.ParentViewModel.DomainContext.Feedbacks.Add(this.Feedback);

                // process changes to server-side through WCF RIA Services
                this.ParentViewModel.DomainContext.SubmitChanges(
                    (o) =>
                    {
                          ...
                    }
      }
}

Inserting the New Post to the Parent View Model

Finally, after the data is saved to the server-side, we’re going to reflect the changes to the UI (View). There are a couple of options to do this. You can either refresh the entire list again to show the latest data, or insert only the new record to the current list (delta approach).

We’re going to use the latter approach because it delivers more responsive user interface by eliminating the client-server round trip. Since we have the reference to the parent view model, we can easily access the Feedbacks collection and perform insertion to the collection. As the Feedbacks collection is using ObservableCollection type and bound to the ItemsSource (see the earlier point above), any changes to the Feedbacks collection will automatically reflect the user interface elements that bound to it. Pretty nice, don’t you agree?

The following code shows the complete process in ExecuteSaveCommand which demonstrates how the new Feedback insertion is implemented.

private void ExecuteSaveCommand(object parameter)
{
      if (ValidateInput())
      {
            // set busy to block user interaction
            this.ParentViewModel.IsBusy = true;
            this.ParentViewModel.DomainContext.Feedbacks.Add(this.Feedback);

            // process changes to server-side through WCF RIA Services
            this.ParentViewModel.DomainContext.SubmitChanges(
                    (o) =>
                    {
                        this.ParentViewModel.IsBusy = false;

                        if (!o.HasError)
                        {
                            // reflect the newly added post to the View
                            this.ParentViewModel.Feedbacks.Insert(0, this.Feedback);

                            // tell the View that we're done with the saving process
                            this.IsSaved = true;
                            this.IsAdding = false;
                        }
                        else
                        {
                            MessageBoxServiceProvider.ShowError(…);
                            o.MarkErrorAsHandled();
                        }
                    }
                    , null);
      }
      else
      {
           FocusErrorField();
      }
}

Download the Solution

Want to create your own rich Silverlight message board? Go ahead, click here to download the C# project solution and modify it as you like. You can use this message board project as the base to quickly jump start your MVVM project.

The C# project solution includes all the codes mentioned in this blog such as the model, view models and converts, the XAML files, and a stripped-down SQL database to minimize download size. You can also find several nice design stuff in the solution such as the minimalist scroll viewer style, iPad callout style, glass button, a vector refresh symbol and much more.

Note that you will need SQL Server Express 2008 installed to run the sample. The latest version of ClientUI is required as well. If you’re still using build 8 (initial RTM build), I highly suggest you to upgrade to the latest version (build 9) for the best stability and performance. Click here to download the latest version, and here to read the installer change log.

Conclusion

So far, you already have some ideas and insights of the key challenges in building Silverlight application using MVVM pattern and WCF RIA Services. Often times, you will deal with the user interface requirements demanded by your users and how you apply the MVVM pattern to address the user interface challenges. Hopefully this message board case study can be useful for you to learn and jump start on using the ClientUI controls with MVVM.

Click here to try the message board online. The following screenshot shows the message board sample that we studied in this post.

ClientUI Live Message Board

Although it may look prettier when integrated into our live showcase (done through SAF and on-demand loading), it’s actually the same project that made available for download.

In the next blog post, I’ll do a quick blog discussing how a ClientUI application can be easily loaded and reused in another ClientUI application domain. For instance, I could load this message board application in a navigation frame of a more complex application, or load it as the content of a window.

For now, I hope you enjoyed the Silverlight message board sample! Let me know if you have any questions or feedback.

All the best,
Jimmy
Chief Software & UX Architect