UXGridView Part 5: Using Custom Editing Controls

In the previous post, I’ve covered the basics of data validation and editing using UXGridView the MVVM-way. In this post, I will show you how to extend UXGridView’s editing experiences by customizing the available column types, the editing template and the editing template selector.

Defining Columns Manually

First of all, you need to set the AutoGenerateColumns property of the UXGridView control to false.

<Intersoft:UXGridView AutoGenerateColumns="False">                
</Intersoft:UXGridView>
    

Next, you specify each column manually as follows.

<Intersoft:UXGridView AutoGenerateColumns="True">
    <Intersoft:UXGridView.Columns>
        <Intersoft:UXGridViewCheckBoxColumn
            Header="Discontinued"
            Binding="{Binding Discontinued}"/>
        <Intersoft:UXGridViewComboBoxColumn 
            Header="Category ID" Width="120"
            DisplayMemberPath="CategoryName" ValueMemberPath="CategoryID" 
            Binding="{Binding CategoryID}"                                                         
            ValueListSource="{Binding Categories,
            Source={StaticResource CategoriesViewModel}}"/>
        <Intersoft:UXGridViewTextColumn 
            Header="Product ID" 
            Binding="{Binding ProductID}" 
            IsReadOnly="True"/>
        <Intersoft:UXGridViewTextColumn 
            Header="Product Name"
            Binding="{Binding ProductName}"/>
        <Intersoft:UXGridViewTextColumn 
            Header="Units In Stock" 
            Binding="{Binding UnitsInStock}"/>
        <Intersoft:UXGridViewTextColumn 
            Header="Unit Price" 
            Binding="{Binding UnitPrice}"/>
        <Intersoft:UXGridViewTextColumn 
            Header="Units On Order" 
            Binding="{Binding UnitsOnOrder}"/>
        <Intersoft:UXGridViewTextColumn 
            Header="Quantity Per Unit"
            Binding="{Binding QuantityPerUnit}"/>
    </Intersoft:UXGridView.Columns>                               
</Intersoft:UXGridView>
    

The results look like the following screenshot.

Dropdown column in UXGridView

Notice that I used three different types of column.

  • UXGridViewTextColumn

    The column has a textual representation for data display and a UXTextBox for data editing control.

  • UXGridViewCheckBoxColumn

    The column has a check box representation to display the data and a UXCheckBox for data editing control.

  • UXGridViewComboBoxColumn

    The column has a textual representation to display the data, a dropdown button to display the data list, and a UXComboBox for data editing control.

Using UXGridViewTextColumn and UXGridViewCheckBoxColumn is pretty straightforward, you just need to set the Binding and Header properties, and you’re all set. For UXGridViewComboBoxColumn, you need to specify the ValueListSource which is required for the combo box data source, along with the DisplayMemberPath and ValueMemberPath.

In this sample, I assigned the ValueListSource  for the UXGridViewComboBoxColumn from a static resource.

<Grid.Resources>
    <ViewModels:CategoriesViewModel x:Key="CategoriesViewModel"/>        
</Grid.Resources>
    

The Categories ViewModel looks like the following code.

using System.Collections.Specialized;
using Intersoft.Client.Data.ComponentModel;
using UXGridView.Samples.ModelServices;

namespace UXGridView.Samples.ViewModels
{
    public class CategoriesViewModel : ViewModelBase
    {
        public CategoriesViewModel()
        {
            this.CategoriesSource = CategoriesRepository.Instance;
            this.LoadCategories();
        }

        private INotifyCollectionChanged _Categories;

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

        public IDataRepository CategoriesSource { get; set; }

        public virtual void LoadCategories()
        {
            this.CategoriesSource.GetData
            (
                (Categories) =>
                {
                    this.Categories = new PagedCollectionView(Categories);
                },
                (error) =>
                {

                }
            );
        }
    }
}

    

Notice that the CategoriesViewModel simply retrieves the data from the CategoriesSource which used repository pattern for loosely-coupled data access. To learn more about data repository pattern, see the ProductsRepository example in my previous blog post.

Using Custom Editing Controls

In many business scenarios, you’re often asked to provide more advanced editing controls in the GridView rather than just a plain textbox, such as DateTimePicker, Slider, MaskedInput, etc. Luckily, it’s fairly easy to implement in UXGridView, thanks to the solid editing architecture. All you need to do is simply creating a data template that contains the input control of your choice, and assign it to the CellEditingTemplate property of the UXGridView.

The following examples show how to customize the editing control of each column through the provided CellEditingTemplate property.

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

<Intersoft:UXGridViewTextColumn Header="Unit Price" Binding="{Binding UnitPrice}"> <Intersoft:UXGridViewTextColumn.CellEditingTemplate> <DataTemplate> <Intersoft:UXCurrencyEditor EditMask="c2" UseEditMaskAsDisplayMask="True" Value="{Binding UnitPrice, Mode=TwoWay}"/> </DataTemplate> </Intersoft:UXGridViewTextColumn.CellEditingTemplate> </Intersoft:UXGridViewTextColumn>
<Intersoft:UXGridViewTextColumn Header="Units On Order" Binding="{Binding UnitsOnOrder}"> <Intersoft:UXGridViewTextColumn.CellEditingTemplate> <DataTemplate> <Intersoft:UXSliderBar Value="{Binding UnitsOnOrder, Mode=TwoWay}" SmallChange="10" LargeChange="20" Maximum="100"/> </DataTemplate> </Intersoft:UXGridViewTextColumn.CellEditingTemplate> </Intersoft:UXGridViewTextColumn>

The following examples show how to use UXDateTimePicker to edit a date time column. Notice that you can bind the BirthDate to the column and directly specify the string format in the binding expression.

<Intersoft:UXGridViewTextColumn 
    Header="Birth Date" 
    Binding="{Binding BirthDate, StringFormat=MM/dd/yyyy}">
    <Intersoft:UXGridViewTextColumn.CellEditingTemplate>
        <DataTemplate>
            <Grid Background="White" Margin="1">
                <Intersoft:UXDateTimePicker 
                    Value="{Binding BirthDate, Mode=TwoWay}" 
                    EditMask="MM/dd/yyyy" 
                    BorderThickness="0"                                                              
                    UseEditMaskAsDisplayMask="True" 
                    VerticalAlignment="Center" 
                    HorizontalAlignment="Stretch"/>
            </Grid>
        </DataTemplate>
    </Intersoft:UXGridViewTextColumn.CellEditingTemplate>
</Intersoft:UXGridViewTextColumn>
<Intersoft:UXGridViewTemplateColumn Header="Address" Binding="{Binding Address}" Width="100"> <Intersoft:UXGridViewTemplateColumn.CellTemplate> <DataTemplate> <TextBlock TextWrapping="Wrap" Text="{Binding Address}" Margin="4"/> </DataTemplate> </Intersoft:UXGridViewTemplateColumn.CellTemplate> <Intersoft:UXGridViewTemplateColumn.CellEditingTemplate> <DataTemplate> <Intersoft:UXTextBox AcceptsReturn="True" TextWrapping="Wrap" Text="{Binding Address, Mode=TwoWay}"/> </DataTemplate> </Intersoft:UXGridViewTemplateColumn.CellEditingTemplate> </Intersoft:UXGridViewTemplateColumn>

As seen in the example above, UXGridView provides a template column named UXGridViewTemplateColumn. This column allows you to change both display and editing appearance. In the example, the UXGridViewTemplateColumn uses a wrapable TextBlock for the display, and a multi-line TextBox for data editing.

You can define literally any kind of input controls that support MVVM in the CellEditingTemplate, including our latest advanced input controls such as UXCalendar, UXDomainUpDown, UXDateTimeEditor, and so forth.

Using Cell Editing Template Selector

A rather unique scenario is where the users would like to have different editing control for the same column which depends on the data being edited. This can be achieved elegantly in UXGridView by using CellEditingTemplateSelector. It works similar to any other template selectors, so the first thing you need to do is creating a template selector class that derived from DataTemplateSelector.

using System.Windows;
using Intersoft.Client.Framework;
using Intersoft.Client.UI.Data;

namespace UXGridView.Samples.Selectors
{
    public class CellEditingSelector: DataTemplateSelector
    {
        public DataTemplate NumericEditor { get; set; }
        public DataTemplate SliderEditor { get; set; }

        public override DataTemplate SelectTemplate(object item, 
                 DependencyObject container)
        {            
            UXGridViewCell cell = container as UXGridViewCell;
            UXGridViewRowBase rowBase = cell.OwningRowBase;
            UXGridViewRow row = rowBase as UXGridViewRow;

            switch (cell.OwningColumn.PropertyName)
            {
                case "UnitsInStock":
                    if (rowBase.IsNewRow || (row != null && row.Index % 2 != 0))
                        return this.SliderEditor;
                    else
                        return this.NumericEditor;                    
            }

            return null;
        }
    }
}

The above code basically selects the editing control differently depending on whether the row is a normal or an alternating row. Notice that the conditioning is scoped to UnitsInStock column only.

Finally, let’s assign the template selector to the UXGridView, see the code below.

<Grid.Resources>
    <DataTemplate x:Key="NumericEditor">
        <Intersoft:UXNumericUpDown Maximum="100"
                   Value="{Binding UnitsInStock, Mode=TwoWay}"
                   HorizontalAlignment="Stretch"
                   VerticalAlignment="Stretch"/>
    </DataTemplate>
    <DataTemplate x:Key="SliderEditor">
        <Intersoft:UXSliderBar
                   Value="{Binding UnitsInStock, Mode=TwoWay}"
                   SmallChange="10" LargeChange="20" Maximum="100"/>
    </DataTemplate>
<Selectors:CellEditingSelector x:Key="CellEditingSelector" NumericEditor="{StaticResource NumericEditor}" SliderEditor="{StaticResource SliderEditor}"/> </Grid.Resources> <Intersoft:UXGridView CellEditingTemplateSelector= "{StaticResource CellEditingSelector}">

As the result, editing the cells of UnitsInStock for the normal row will show a UXNumericUpDown control. See the illustration below.

UXNumericUpDown for normal row editing

While editing the cells for the alternating row of the same column will show a UXSliderBar control instead.

UXSliderBar for alternate row editing

That’s all for now, I hope this post gives you some cool ideas on using the available column types and customizing the editing controls in UXGridView. All samples I used in this blog post are available in our latest CTP release. Click here to download it now and get yourself familiar with the MVVM implementation in the UXGridView, starting from the data retrieval, handling the data editing, to customizing editing controls.

Best Regards,

Andry

Advertisements

3 thoughts on “UXGridView Part 5: Using Custom Editing Controls

  1. Pingback: UXGridView CTP3: Feature-complete Grid for Silverlight & WPF | Intersoft Solutions Corporate Blog

  2. Steve Brouillard

    Andry,

    I’m evaluating your ClientUI controls now and am trying to do something similar. I’m having some challenges. Is there a working sample of this post? Is there someone I can contact?

    Reply
  3. jimmyps

    Dear Steve,

    Thanks for your interest in ClientUI controls. Yes, we have officially released UXGridView, you can download the setup at http://www.clientui.com/download. After installation, head to Intersoft WebUI Studio program group, expand Silverlight 4 group, and locate the UXGridView Samples under the Development Solutions group.

    You can post your questions to http://www.intersoftpt.com/Community/ClientUI. For pre-sales questions, reach us at sales@intersoftpt.com. Thanks!

    Best,
    Jimmy

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s