PivotViewer, SilverBullet

PivotViewer and MVVM

PivotViewer series

  1. Building your first PivotViewer application
  2. Runtime PivotViewer collection creation
  3. PivotViewer – Working with Facets
  4. Handling PivotViewer events
  5. PivotViewer – Custom actions
  6. PivotViewer and MVVM

Intro

The MVVM patterns is a commonly used pattern in Silverlight. Because of databinding MVVM suits perfectly for WPF and Silverlight. But use it only if appropriate. Often the pattern is used when it isn’t necessary. The usage of any pattern should be a helping tool, not an enforced law. Having that of my chest, lets look at the Silverlight PivotViewer control in combination with the MVVM pattern.

To make a long story short, the PivotViewer control isn’t suitable for use in MVVM out of the box. But there are a few ways you can make it work.

 

Wrapping the PivotViewer in a UserControl

The most simple way to get the control to work in an MVVM application is to place the control in a UserControl. You can use this control in your View and bind to properties you add to the UserControl. You’ll have to add dependency properties to the UserControl for each property you want to data bind to. The downside of wrapping the PivotViewer control in a UserControl is that you will have to add code to the CodeBehind of the UserControl.

 

For example a URL where the .CXML file is located. If this value changed you would like to load the collection. In the current version of the PivotViewer the only way to do this is to call the LoadCollection method on the PivotViewer control. By adding a dependency property to the UserControl you can bind a property of the ViewModel to this and have it load a collection on changes.

This dependency property  with its “OnChange” method might look something like this:

public string UrlSource{
    get { return (string)GetValue(UrlSourceProperty); }
    set { SetValue(UrlSourceProperty, value); }
}

public static readonly DependencyProperty UrlSourceProperty =
    DependencyProperty.Register("UrlSource",
                                typeof(string),
                                typeof(PivotViewerUserControl),
                                new PropertyMetadata(string.Empty,
                                                        OnUrlSourceChanged));
 
private static void OnUrlSourceChanged(DependencyObject d,
                                        DependencyPropertyChangedEventArgs e)
{
    if (!DesignerProperties.GetIsInDesignMode(d))
    {
        var userControl = (PivotViewerUserControl) d;
        userControl.Pivot.LoadCollection((string) e.NewValue,
                                             string.Empty);
    }
}

A logical next step would be to add a dependency property for the ViewerState parameter of the LoadCollection method and call it only when both are set or if the UserControl is Loaded.

To get notified when the selected item changed you can use an ICommand. Add a dependency property of type ICommand to the UserControl to be able to bind an implementation of the ICommand from the ViewModel to it. The property changed event on the PivotViewer control is handled. When the “CurrentItemId” property changes, thus the selected item changes, the event is executed. As a small extra feature the item is looked up on the PivotViewer and the whole PivotItem is passed as a parameter to the execute method.

public PivotViewerUserControl()
{
    InitializeComponent();
    Pivot.PropertyChanged += Pivot_PropertyChanged;
}

public ICommand SelectedItemChangedCommand
{
    get { return (ICommand)GetValue(SelectedItemChangedCommandProperty); }
    set { SetValue(SelectedItemChangedCommandProperty, value); }
}

public static readonly DependencyProperty SelectedItemChangedCommandProperty =
    DependencyProperty.Register("SelectedItemChangedCommand",
                                typeof(ICommand),
                                typeof(PivotViewerUserControl),
                                new PropertyMetadata(null));

private void Pivot_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "CurrentItemId")
    {
        if (this.Pivot.CurrentItemId == null)
        {
            // deselection
            this.SelectedItemChangedCommand.Execute(null);
        }
        else
        {
            // selection
            PivotItem item = Pivot.GetItem(Pivot.CurrentItemId);
            this.SelectedItemChangedCommand.Execute(item);
        }
    }
}

Extending the PivotViewer control itself

Another way to get to PivotViewer to work in an MVVM application is to extend the PivotViewer itself. The dependency properties you’ll be adding to the control are pretty much the same as the ones shown in the previous section, with the extend that you have better access to the guts of the PivotViewer control. This way you have access to the Custom Actions for example.

Where to go next

You could start by implementing all properties of the PivotViewer control as dependency properties and add a ICommands to event handlers. Maybe you can find constructions where you can extend the control with your own needs

I just hope that in the next version of the PivotViewer Microsoft did this boring work for us so we don’t have to.

I don’t have plans for a next tutorial on the PivotViewer, yet. If you have question or requests just let me know and I’ll see if I can help you. If you want to be the first to when a new tutorial is available, you can subscribe to the RSS-Feed or follow me on twitter.

Technorati Tags: silverlight,pivotviewer

Share

 

5 comments

  1. Hi Timmy,
    None of the links to your previous PivotViewer posts work – all give a 404 not found error. Have you deleted them or have they moved somewhere else? Was hoping to review them all.

  2. Hi Timmy,
    Been following this tutorial and all the articles have been a real help. However, I guess the previous posts under this tutorial are currently not available. Can you please make them available, as I usually use it for my reference in my work?

  3. Hi Ian and Abhi,

    Thanks for pointing this out! It seems something went wrong when moving things over to my new blog. I’ve fixed the links. The code needs to be formatted again too. This will take some more work and will be done in the next few weeks.

  4. Hi Timmy,
    I would like to thank you for this wonderful tutorial. I has helped me a lot in my work.
    I searched the whole net and yet got no other tutorial like yours. You have really done a fantastic job with this tutorial.

    Thanks again.

Leave a Reply

Seo wordpress plugin by www.seowizard.org.
%d bloggers like this: