Silverlight PivotViewer and SharePoint

 

Microsoft just released a new control PivotViewer for Silverlight. 

http://www.microsoft.com/silverlight/pivotviewer/

If you haven't seen this yet - go check out the video then come back, I'll wait here.

 

It's a web-based control to provide pivot functionality for datasets.  For fixed data - you can pre-generate the data set. For dynamic data, the collection could be generated dynamically and served.

So what would happen if you throw it at SharePoint, I ask?

The initial results are astounding!  Check these out:

image

Figure: Connecting it to listdata.svc OData service

At the root level it really is quite boring.

 

image

Figure: Connecting to a document library OData service

OK this is getting fun.  Facets!  Sort/Display/Zoom

image

Figure: Sorting the document library by Modified date

You probably can see I've uploaded a bunch of documents in the last hour :-)

 

The screenshots don't do this justice - when you filter down, change sort… the boxes fly all over the place it's as if I'm literally shaking SharePoint apart to zoom in on my data.

 

So it looks like I'll be extremely busy next couple of weekends and evenings:

  • Generate collection data across site - this will let me filter the "Path" facet to select which list/document library I'm after
    • What does this mean for big sites?
  • Add more visualizers, use Word/PPT thumbnails
  • Create configurable background colours for different content types
  • Add a contextual menu and hook it back through SharePoint actions
  • And the Holy Grail - is it possible to make this work as a Sandbox Solution?
    • The current sample reference application requires IIS HttpHandlers to serve dynamic collection data consumed from OData. 
    • Sandbox solution problem may be tricky.

 

It's times like this I stood back and appreciate what Microsoft does.  You guys are awesome.  Different teams produce different software and they just magically work together.  Makes us look like heroes.

/Salute

Silverlight Unit Testing - adding a timeout to EnqueueConditional

Since a lot of Silverlight work is asynchronous in nature, the Silverlight testing framework has many helper functions to essentially do "non blocking wait until something happens"

The curious one to me is EnqueueConditional(Func<bool> conditionalDelegate

This one essentially waits until the condition is true - so you can call a method to populate your view model with data, and then wait until data.Count > 0

But the method has no support for timeout.  It can, and will, hold the unit testing framework in progress forever.

Here's my little tweak to the method.

        public override void EnqueueConditional(Func<bool> conditionalDelegate)
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 5);
            timer.Tick += delegate
            {
                // remember to stop timer or it'll tick again
                timer.Stop();
                throw new TimeoutException();
            };
            EnqueueCallback(delegate
            {
                timer.Start();
            });
            base.EnqueueConditional(conditionalDelegate);
            EnqueueCallback(delegate
            {
                timer.Stop();
            });
        }

Here's the unit test to go with it

        [TestMethod]
        [TestProperty("TestCategory", "Silverlight")]
        [Asynchronous]
        [ExpectedException(typeof(TimeoutException))]
        public void Test_Timeout()
        {
            EnqueueConditional(delegate
            {
                // return?  never!
                return false;
            });

            EnqueueTestComplete();
        }

And one more tweak in the App.xaml.cs

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is TimeoutException)
            {
                e.Handled = true;
                // stop any timeoutexception here or it'll bubble to the DOM
                return;
            }

            ...
        }

Here's the result picture:  Running just slightly over 5 seconds.

image

 

Updated: added a result picture.

Silverlight first asynchronous test run twice

I'm observing a pretty odd behaviour - the first test of my MVVM is running twice.

Exhibit Original code:

 
    [TestMethod, Asynchronous]
public void VMConnectTest() { ViewModel clientVM = CreateVM(); #region connect clientVM.Connect.Execute(null); base.EnqueueConditional(delegate { return clientVM.IsConnected; }); #endregion base.EnqueueTestComplete(); }

I have a break point in CreateVM - and it's firing twice, off the same line.

Changing the code to:

    [TestMethod, Asynchronous] 
public void VMConnectTest() { ViewModel clientVM = null; #region connect base.EnqueueCallback(delegate { clientVM = CreateVM() clientVM.Connect.Execute(null); }); base.EnqueueConditional(delegate { return clientVM.IsConnected; }); #endregion base.EnqueueTestComplete(); }

And now the CreateVM only runs once.

I suspect the Asynchronous test has a bug regarding mixing which thread is suppose to be creating the VM.  In this case, it's running twice.  Throwing everything onto the test stack seems to have fixed this, but makes the code look more complex than usual.

Silverlight Unit Testing Framework - modify/remove Tag Expressions dialog

The default Silverlight Unit Testing framework project has a lovely Tag Expressions welcome dialog that lets you decide (within 5 seconds), whether you want to run a subset.

How do you get rid of it?

image

 

Turns out it's pretty easy:

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            UnitTestSettings settings = UnitTestSystem.CreateDefaultSettings();
            settings.StartRunImmediately = true;
            settings.ShowTagExpressionEditor = false;

            RootVisual = UnitTestSystem.CreateTestPage(settings);
        }

Use UnitTestSystem.CreateDefaultSettings() to get you started quickly, if you create your own UnitTestSettings class you will have to set up your own Test Harness or you'll face this Exception:

 

Test harness was not specified on test harness settings object. If a test harness settings object was passed in, please verify that it contains a reference to a test harness.

C# Anonymous Delegate Syntax

In the effort to save key strokes, sometimes I wonder if C# code is becoming a bit unreadable.

Exhibit Original:

private void VMIsConnected() {
    Assert.IsTrue(vm.IsConnected);
}

...
EnqueueCallback(this.VMIsConnected);

 

Exhibit A:

EnqueueCallback( delegate {
    Assert.IsTrue(vm.IsConnected);
} );

 

Exhibit B:

EnqueueCallback( () => Assert.IsTrue(vm.IsConnected );

 

Which one do you use?

I like A.  Simple enough without extra function signature, yet readable.  The ( ) in Exhibit B scares me.