Monthly Archives: April 2011

Customizing the PivotViewer

For those of you who haven’t seen it yet, Microsoft released a very powerful data visualization control called the PivotViewer. It leverages the deep zoom feature to perform filtering and sorting of complex data objects allowing the user to navigate through dense data in an efficient (and fun) way. The only problem is that it is a closed source library and the control implementation doesn’t allow for templates or styling.

Luckily there are a few tricks you can play to make substantial changes to the appearance and behavior of the PivotViewer if you’re willing to work with the codebehind. Xpert360 Ltd. published a blog post titled Adventures with PivotViewer┬áin which they explain how to effectively re-skin the PivotViewer. After rifling through the assemblies using Reflector I found that you can get access to much more of the core functionality by leveraging some of the classes exposed through the library’s internal namespace.

The PivotViewer control that they give you access to through the System.Windows.Pivot namespace is a wrapper around the CollectionViewer MVVM structure exposed in the Microsoft.Pivot.Internal.* namespaces. Almost all of the members that you would wish to be able to modify are exposed by obtaining references to the view, view model, and model. This can be achieved trivially by subclassing PivotViewer and overriding the OnApplyTemplate() function.

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    Grid partContainer = (Grid)this.GetTemplateChild("PART_Container");

    CollectionViewerView cvv =
        ((CollectionViewerView)(partContainer).Children[0]);
    CollectionViewerViewModel cvvm =
        (CollectionViewerViewModel)ViewBehaviors.GetViewModel(cvv);
    CollectionViewerModel cvm =
        (CollectionViewerModel)ViewBehaviors.GetModel(cvv);
}

Once you obtain these three references, the sky is the limit. One example of what I was able to use these for was changing the default view. The data that I am displaying lends itself almost exclusively to the histogram view, but the default is the grid view. Whenever the sort category was changed automatically by drilling down through a single histogram column the view was reset to grid view. This resulted in an unpleasant user experience because it required mousing all the way across the screen to keep setting the view back to histogram mode.

I was again able to leverage Reflector to find that the views are initialized into a ViewSelectionState object exposed through a property on the model. Each view has an entry in the ViewDataObjects array on the ViewSelectionState, with the grid view data object in the first index and the histogram in the second. By reversing them in the OnApplyTemplate() function I was able to change the default behavior of the PivotViewer.

cvm.ViewSelectionState.ViewDataObjects =
    cvm.ViewSelectionState.ViewDataObjects
        .Reverse()
        .ToArray();

Another useful feature I was able to add was a GridSplitter next to the filter panel. Many of our values are long and were being trimmed by the filter panel, so by adding the GridSplitter I was able to give users access to the complete values as necessary. This improvement leveraged the view reference to modify the visual tree.

FrameworkElement filterPane =
    (FrameworkElement)cvv.FindName("PART_FilterPaneContainer");
Grid filterParent = (Grid)filterPane.Parent;

GridSplitter splitter = new GridSplitter();
splitter.SetValue(Grid.ColumnProperty, 0);
splitter.Style =
    (Style)App.Current.Resources["RightVerticalGridSplitterStyle"];
BindingOperations.SetBinding(splitter, GridSplitter.VisibilityProperty,
    new Binding("Opacity")
    {
        Source = filterPane,
        // Custom implementation converting 0 to false, other to true
        Converter = new VisibilityConverter()
    });
filterParent.Children.Add(splitter);

filterPane.Margin = new Thickness(
    filterPane.Margin.Left,
    filterPane.Margin.Top,
    filterPane.Margin.Right + splitter.Width,
    filterPane.Margin.Bottom);

Please leave a post if you come up with any other useful tweaks!


Dispatcher.DelayedInvoke

There are many cases when a developer wants a delayed action to occur. This may be a simple timed reaction to a user event, a web service poll or retry loop, or any variety of task. If you’re feeling creative you could use a Storyboard or a complicated thread implementation, but I’d like to share an elegant solution that allows you to write delayed invokes on the UI thread like this:

Dispatcher.DelayedInvoke(TimeSpan.FromSeconds(30), () => { DoStuff(); });

This syntax is possible by leveraging the Extension Method notation. For those unfamiliar with extension methods, the general idea is that it is possible to define a static function where the first parameter is defined with a “this” keyword in front of it. This indicates to the compiler that any instance of the type of that first parameter should have the function applied to it. For example:

// Note the "this" prefix before the type specification.
public static string GetFullName(this User user)
{
	return String.Format("{0}, {1} {2}",
		user.LastName, user.FirstName, user.MiddleInitial);
}

public void TestFunction()
{
	User user = new User("John", String.Empty, "Doe");
	string fullName = user.GetFullName();
}

The real power of these extension methods is that you can add additional functionality to objects that are externally instantiated or that aren’t inheritable. The Dispatcher class is a perfect example of both. It is a sealed class, and the Dispatcher references exposed through the property on DependencyObjects is instantiated by the framework.

Getting back to the issue of the DelayedInvoke extension method, I decided to use a Thread with Sleep implementation so as not to use up a ThreadPool thread. There are many ways to implement a wait, and you can easily swap in another approach. Here is my full implementation:

public static class DispatcherExtensions
{
    // Invocation without arguments.
    public static void DelayedInvoke(this Dispatcher dispatcher, TimeSpan delay, Action action)
    {
        Thread thread = new Thread(DoDelayedInvokeByAction);
        thread.Start(new Tuple<Dispatcher, TimeSpan, Action>(dispatcher, delay, action));
    }

    private static void DoDelayedInvokeByAction(object parameter)
    {
        Tuple<Dispatcher, TimeSpan, Action> parameterData = (Tuple<Dispatcher, TimeSpan, Action>)parameter;

        Thread.Sleep(parameterData.Item2);

        parameterData.Item1.BeginInvoke(parameterData.Item3);
    }

    // Invocation with arguments.
    public static void DelayedInvoke(this Dispatcher dispatcher, TimeSpan delay, Delegate d, params object[] args)
    {
        Thread thread = new Thread(DoDelayedInvokeByDelegate);
        thread.Start(new Tuple<Dispatcher, TimeSpan, Delegate, object[]>(dispatcher, delay, d, args));
    }

    private static void DoDelayedInvokeByDelegate(object parameter)
    {
        Tuple<Dispatcher, TimeSpan, Delegate, object[]> parameterData = (Tuple<Dispatcher, TimeSpan, Delegate, object[]>)parameter;

        Thread.Sleep(parameterData.Item2);

        parameterData.Item1.BeginInvoke(parameterData.Item3, parameterData.Item4);
    }
}

It’s important to note that the thread work function calls the Dispatcher‘s BeginInvoke function. The main reason for exposing the DelayedInvoke function as an extension of the Dispatcher is that it is implicit that the callback be performed on the UI thread. Even when the DelayedInvoke function is called from a non-UI thread, all operations performed in the supplied delegate can be safely made against UI objects because of the Dispatcher.BeginInvoke call.

Hopefully this makes your life a little easier.


Silverlight vs. HTML5

I was watching Giorgio Sardo’s presentation on HTML5 for Silverlight Developers at MIX 11 this morning and it got me thinking about the long term viability of Silverlight in light of the meteoric rise of HTML5. It doesn’t take much internet searching to turn up a lot of mudslinging in the language debate, but I think it’s important to step back and consider each of these languages objectively as possible for their strengths. To me this boils down to portability vs. functionality.

There is no comparison on the portability front. HTML5 is the clear winner, having broad support on essentially all platforms including low-power and mobile devices. Because Silverlight is a closed platform, open-source runtimes (See Moonlight) lag behind in their implementations of new features. Between adoption rates for Silverlight on Windows machines hovering between 60% and 70% and the limited implementations available on other operating systems, if portability is a major concern for your project there’s really no way to beat HTML5. This isn’t to say that Silverlight should be written off as irrelevant moving forward, however.

As Giorgio points out in his presentation, HTML5 exists today because of the legacy that browser plugins have provided. Most of the features that it offers have been available in Flash and Silverlight for many years, and they are drawn from these frameworks in an attempt to replicate the user and developer experiences in an open, cross-platform way. These plugins have set the standard for what users expect on the internet, and despite all of the hype about the HTML5 being the next big thing, Flash and Silverlight still continue to set the pace for new features.

This isn’t to say that the flow of ideas is entirely a one way street. There are a lot of smart people working on the HTML5 standard and writing libraries to support it. The fact of the matter is though that the HTML5 standard is maintained by a large consortium of powerful entities, sometimes with conflicting interests and voices. There is a lot of inertia when making changes to such a widely distributed standard as HTML when compared to a proprietary closed standard. Microsoft has a clear direction for their Silverlight platform and the executive clout to make platform improvements happen in a timely manner.

In most cases neither HTML5 nor a plugin framework like Silverlight or Flash are perfectly suited for any particular development task. In fact, compared side-by-side they are all almost identical in their capabilities. When it comes time to decide which language to use for a new web-based project it comes down to weighing the portability vs. functionality question I opened this post with.

The greatest strength of HTML5 is that your application can be written once and deployed anywhere. This is of particular benefit when creating something for consumption by the general public where you are guaranteed to see a wide variety of client configurations. If this portability isn’t a great concern, for example in an enterprise environment, then the bleeding-edge technological benefit of using a plugin based framework like Silverlight may outweigh it.


Introduction

This is a brand new blog for me so I’d like to take a moment to talk about who I am and why I’m starting this blog. I’ll be filling out more of my personal details with regard to my experience on the “About” page, but in short, I’m currently a Silverlight developer. I work at an electronics manufacturing company in Beaverton, Oregon called Vanguard EMS developing software tools for optimizing their internal processes. By education, I’m a physicist, but I got into coding as a kid and ended up doing it professionally because I love it!

The idea behind this blog is to give me an avenue for publishing some of the tips, tricks, and opinions I’ve come up with over the course of my journey through software development. The internet has proven to be an invaluable resource when solving problems, and I feel like it’s my duty to help give back to the online community. I promise to do my best to provide useful information without boring you to death or forcing you to wade through paragraphs of drivel for the good stuff.

With that, I have a beta deployment to address. Stay tuned!