Follow Me on Instagram Subscribe via RSS Feed

PivotViewer Multi-Valued Properties

February 20, 2012

Defining properties in the new PivotViewer is rather straight forward, but I was recently asked about defining a multi-valued property.  In the original PivotViewer, the CXML item would simply contain multiple entries for a given property and the PivotViewer would do the rest.  Fortunately, PivotViewer still handles most of the details for us, with a minor catch.

Mapping a multi-valued list to PivotViewer is basically the same as a single valued property.  The same property types apply and the actual definition is identical.

For this project, we are going to borrow the sample project from the PivotViewer Basics Series.  You can get the base project from the Client-Side Collections here : PVB01_ClientSideCreation.zip.

Just to get a base-line of where we are starting from, you can run the project and you should see a collection of colored trading cards with some simplistic properties.

image

If you take a look at our XAML in the MainPage, we have a DateTime property defined as Stamp.  If you look at the DemoItem there is a BuildData() method that generates our data for the collection, which includes a date for our Stamp property.

What if we wanted to track multiple dates for this property?  Since that is what this post is about, it seems a relevant question.  From a XAML and PivotViewer point of view, we don’t have to make any changes.  PivotViewer will accept a single DateTime value or a collection of DateTime values.

With that taken care of, we can now shift our focus to the DemoItem class itself.  The first thing we need to do is change the Shift property to a collection.  For simplicity we will create a List<DateTime>.  However, if you create a collection that implements the INotifyCollectionChanged interface, such as an ObservableCollection, PivotViewer will update the item whenever that collection changes.  Since we are created a static list when the object is created, a List<> will work just fine in this example.

The next step is to modify the BuildData() method to populate our Stamp property with a collection of DateTimes.  Here is the modified portions of our DemoItem class.

    public class DemoItem : INotifyPropertyChanged
    {

        ...

        private List<DateTime> _stamp;
        public List<DateTime> Stamp
        {
            get { return _stamp; }
            set
            {
                _stamp = value;
                NotifyProperty("Stamp");
            }
        }

        public static ObservableCollection<DemoItem> BuildData()
        {

             ...
                itm.Stamp = new List<DateTime>() 
                            {DateTime.Now.AddDays(-1 * i),
                             DateTime.Now.AddDays(-1 * 5 - 20)};
 
             ...
        }

     ...

    }

image

Now if we run our project and select an item, you will see that the Stamp property in the detail pane has multiple values in it.  Seems simple enough, right? With your application running, change the sort property to Stamp. Oops, seems we get the following error:

“Failed to compare two elements in the array.”

The reason for this error is that PivotViewer is unable to sort the items based on a List<DateTime> data type.  If you think about it, it makes sense.  If you have two lists of DateTime, which one comes first?  It really depends on your usage of it and therefore we will need to write some code.

To accomplish this we are going to create a new class : DateTimeList.  The class will inherit the List<DateTime> as well as implement the IComparable interface.  The IComparable interface adds a single method to our class, CompareTo.  For our case, we are going to sort based on the first DateTime in the list.  Our new class will look like this:

public class DateTimeList : List<DateTime>, IComparable
{

    public int CompareTo(object obj)
    {
        return this[0].CompareTo((obj as DateTimeList)[0]);
    }
}

Now let’s change our DemoItem to use our new class instead of the original List<DateTime>.

 

    public class DemoItem : INotifyPropertyChanged
    {

        ...

        private DateTimeList _stamp;
        public DateTimeList Stamp
        {
            get { return _stamp; }
            set
            {
                _stamp = value;
                NotifyProperty("Stamp");
            }
        }

        public static ObservableCollection<DemoItem> BuildData()
        {

            ...
                itm.Stamp = new DateTimeList 
                  {DateTime.Now.AddDays(-1 * i), 
                  DateTime.Now.AddDays(-1 * 5 - 20)};

            ...
        }

    }

Rerunning our application, we can now select Stamp as the sort property and PivotViewer will sort based on our definition.  It is worth noting that if you did not have the “CanFilter” option set on the Stamp PivotProperty, it would not be necessary to create a new collection object. 

The completed project of for this post can be found here: PV_MultiValued.zip

Comments (1)

Trackback URL | Comments RSS Feed

  1. VK says:

    Great tutorial! Thanks!

Leave a Reply