Design time data – Second look

In my previous blog I went through how Jounce template for Silverlight application creates default application and generates plumbing in place to use Design Time data. All the projects I have worked on, we completely ignore it. For the last couple of months, I have been consciously taking extra steps to use Design Time data. As I mentioned in my multiple posts, it is simply of the best feature most of every one ignores. Without doubt, in my opinion it is one of the easiest one to achieve without lot of learning curve and available out of the box. Jounce Silverlight Application template already creates all interfaces and implementation in place to use it. In my previous post I went though what is available out of the box. In this blog, I am going to take it one extra step.

I need to emphasis here, this would be lot more easier if we would use Expression Blend. Since we are not designers, we are going to look at solving the problem traditional way as a coder.

Here are the requirements for the application.

1. It has to display the data in grid format.

2. The column order has to be Name, Age, Salary and Sex.

3. Salary has to currency formatted and should be right aligned.

4. In case the record allows ‘IsEnable’ then change the background color of the salary field to be RED.

First we are going to create a Silverlight application using Jounce Silverlight Application framework. What I am going to do is to crate a grid, which will show our favorite Person class information. So here is our person class.

public class Person : INotifyPropertyChanged
    {
        public string Name { get; set; }
        public int Salary { get; set; }
        public char Sex { get; set; }
        public int Age { get; set; }
        public bool IsEnabled { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

Normally the way, I go about doing is, to crank up the XAML and run the application and then see if the grid shows my data properly if not tweak the XAML, rinse and repeat the process till you get what you want. In my opinion we are wasting time on this, where all the requirement in this case can be verified in the IDE itself. Lets see how it should have been done (IMHO).

Since we have created the Silverlight application using Jounce Template, it already created the interface for data layer. I removed the default string variable to List of Person, like the following in the IMainViewModel.cs

using System.Collections.Generic;
namespace FilteringIssueOnCellTemplate.Common
{
    public interface IMainViewModel
    {
        List<Person> People { get; }
    }
}

Just a refresher here, if you look at the solution, we are after ‘DesignMainViewModel.cs’ under SampleData. This particular class will be used for design time data. We will see later how it is hooked up for design time data. For now, lets change this class to return bunch of dummy data which covers our requirement.

using System;
using FilteringIssueOnCellTemplate.Common;
using System.Collections.Generic;

namespace FilteringIssueOnCellTemplate.SampleData
{
    public class DesignMainViewModel : IMainViewModel
    {
        public List<Person> People
        {
            get
            {
                List<Person> _ppl = new List<Person>();
                _ppl.Add(new Person() { Age = 20, Name = "A", Salary = 10000, Sex = 'F', IsEnabled = true });
                _ppl.Add(new Person() { Age = 20, Name = "B", Salary = 10000, Sex = 'M', IsEnabled = false });
                _ppl.Add(new Person() { Age = 20, Name = "C", Salary = 10000, Sex = 'F', IsEnabled = false });
                _ppl.Add(new Person() { Age = 20, Name = "D", Salary = 10000, Sex = 'F', IsEnabled = true });
                _ppl.Add(new Person() { Age = 20, Name = "E", Salary = 10000, Sex = 'M', IsEnabled = false });
                _ppl.Add(new Person() { Age = 20, Name = "F", Salary = 10000, Sex = 'M', IsEnabled = true });
                return _ppl;
            }
        }
    }
}

As you can see, I have few of the records set to IsEnabled to True so we can see if the XAML I wrote really works.

<Grid x:Name="LayoutRoot" Background="White"
          d:DataContext="{d:DesignInstance sampleData:DesignMainViewModel, IsDesignTimeCreatable=True}">
</Grid>

By default the layout grid looks like this. If you notice, the second line, where d:DataContext is set to our sample view model. So Lets put our data grid control in there and see how it looks. So I am going to add my grid and bind it to Person collection ‘People’ like the following

<c1:C1FlexGrid ItemsSource="{Binding People}"/>

Now if you see the design screen after adding the line would like the following

image 

So we need to change the column order and display only required fields. So I modify the XAML like the following

<c1:C1FlexGrid ItemsSource="{Binding People}">
            <c1:C1FlexGrid.Columns>
                <c1:Column Binding="{Binding Name, Mode=TwoWay}"/>
                <c1:Column Binding="{Binding Age, Mode=TwoWay}"/>
                <c1:Column Binding="{Binding Salary, Mode=TwoWay}"/>
                <c1:Column Binding="{Binding Sex, Mode=TwoWay}"/>
            </c1:C1FlexGrid.Columns>
        </c1:C1FlexGrid>

If you are like the normal developer here you would compile and run to see how it looks, I say ‘stop’ and look at the design panel

image 

You might have noticed, Name field appears twice so we have a bug in the XAML.  It is easy, by default, data grid AutoGenerateColumn is True so we change it to False. Now after adding and look at the design Panel, the duplicate column is gone.

image

Now we are going to tweak the XAML to add additional requirements. lets look at the simple ones, Need to change the formatting of the column to currency and right aligned. Modify the salary column to the following

<c1:Column Binding="{Binding Salary, Mode=TwoWay, StringFormat=c}" HorizontalAlignment="Right"/>

 

The interesting part here is that, as you change you can see design panel changes. With the above changes, now you got the gird to look almost close to what you want except the back ground color.

image

Now we need to set the back ground color of the salary, you can not do dynamic binding to back ground for a column, only way you can do that is through the cell template.

Before I write cell template, I am going to write a converter which will check and see if IsEnabled is set to true or false like the following

public class ColorConverterForRowType : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool item = (bool)value;

            if (item == false)
                return new SolidColorBrush(Color.FromArgb(255, 0xde, 0xe2, 0xe6));

            return new SolidColorBrush(Colors.Red);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    }

Now add the cell template in the XAML as follows

 

<c1:Column Binding="{Binding Salary, Mode=TwoWay, StringFormat=c}" HorizontalAlignment="Right">
                    <c1:Column.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Border Background="{Binding IsEnabled, Converter={StaticResource ColorConverterForRowType}}"/>
                                <TextBlock Text="{Binding Salary, Mode=TwoWay, StringFormat=c}" HorizontalAlignment="Right"/>
                            </Grid>
                        </DataTemplate>
                    </c1:Column.CellTemplate>
                </c1:Column>

Now just compile the code and see what is in the panel

image

Look at it, we did not run once and we got the look and feel the initial requirement. It is very easy and avoid all those multi runs to see if the screen looks like we need.

Advertisements

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