Silverlight 5 new PivotViewer - detect when trading cards have completed rendering

616 views Asked by At

I am looking for an event (or another mechanism / workaround) that I can use to know when rendering of trading cards has completed in the Pivot Viewer control. I am using the SL5 version of the control and adding to its ItemSource (via an observable collection). Currently, there is quite a lag between providing the control with data and seeing something animate on the pivot viewer control. My thread that populates ItemSource exits and after 5-10 seconds of staring at a blank screen, the user eventually sees the trading cards images. The built-in events don't support any indication of when rendering of the trading card images is in a 'ready' state.

3

There are 3 answers

0
JasonRShaver On

I looked into this (talking to the PivotViewer developers) and there is currently nothing you can handle to figure out when rendering has completed.

The best option open to you may be to investigating the SL rendering performance and look for the drop after loading a collection. Not pretty and might not work anyway...

Starting point: http://msdn.microsoft.com/en-us/library/bb980092.aspx

Jason R. Shaver Previous PM for PivotViewer

0
Steven Hollidge On

I had the same issue so I coded up my own solution by extending the pivotviewer control: http://stevenhollidge.blogspot.ch/2012/12/pivotviewer-itemsloaded-event.html

I hope someone finds this useful!

0
Steven M On

The best way I've found to detect when the visuals are loaded is to find the MultiScaleImage object and detect whether the images are "Downloading" or "Idle", as well as what the viewport of an image is:

Here's how you can get at that object on the PivotViewer in SL5:

Subclass the PivotViewer object and place the following in OnApplyTemplate() override:

PartContainer = (Grid)this.GetTemplateChild("PART_Container");
cvv = (PartContainer).Children[2] as CollectionViewerView;

if (cvv != null)
{
    cvvm = ViewBehaviors.GetViewModel(cvv);
    Grid container = cvv.Content as Grid;
    Border viewerBorder = container.Children[1] as Border;
    Grid cvGrid = viewerBorder.Child as Grid;
    cvc = cvGrid.Children[0] as CollectionViewContainer;
}

Then you have a reference to cvv - the CollectionViewerView.

When you set your ItemsSource on the PivotViewer object, start a timer that will check every 300 ms or so for this:

ItemViewerView ivv = ((Grid)(((UserControl)(cvc.Content)).Content)).Children[0] as ItemViewerView;
Grid g = (((Grid)ivv.Content).Children[0] as Grid);
ContentControl cc1 = (g.Children[0] as ContentControl);
if (cc1 != null)
{
    Canvas cvs = cc1.Content as Canvas;
    if (cvs != null && cvs.Children.Count > 0)
    {
        var contentControl = cvs.Children[0] as ContentControl;
        if (contentControl != null)
        {
            MultiScaleImage x = contentControl.Content as MultiScaleImage;
            bool isIdle = x.Source != null && !x.IsDownloading && x.IsIdle;
            // This could be more precise, but the origin is by default set to 99999 when a new image is loaded in - we're watching for when this value changes.                
            bool inViewPort = x.SubImages[x.SubImages.Count - 1].ViewportOrigin.X < 999999;
            // if both of these boolean values are true, then the images will be displaying on the screen.
        }
    }
 }

Note this is SL .dll with version 5.0.61118 (future version this code will most likely break)