Quantcast
Channel: Timmy Kokke » PivotViewer
Viewing all articles
Browse latest Browse all 6

PivotViewer and MVVM

$
0
0

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: ,

Share

 


Viewing all articles
Browse latest Browse all 6

Latest Images

Trending Articles





Latest Images