<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:series="http://unfoldingneurons.com/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>.NET Rocker</title>
	
	<link>http://tonychampion.net/blog</link>
	<description>The .NET ramblings of Tony Champion</description>
	<lastBuildDate>Tue, 27 Mar 2012 15:35:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/tonychampion" /><feedburner:info uri="tonychampion" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Hacking PivotViewer : Pan</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/Y8A6U2YvROY/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-pan/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 15:25:00 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[PivotViewer]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[pan]]></category>
		<category><![CDATA[pivotviewer]]></category>
		<category><![CDATA[silverlight 5]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=396</guid>
		<description><![CDATA[Continuing on with the Hacking PivotViewer series, in this post we will look at accessing and modifying the current pan position.&#160; As I mentioned in the first post, Hacking PivotViewer : Zoom, there is always more than one way to attack some of these problems.&#160; In doing the research for this post, I came across [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing on with the <a href="http://tonychampion.net/blog/index.php/series/hacking-pivotviewer/">Hacking PivotViewer series</a>, in this post we will look at accessing and modifying the current pan position.&#160; As I mentioned in the first post, <a href="http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-zoom/">Hacking PivotViewer : Zoom</a>, there is always more than one way to attack some of these problems.&#160; In doing the research for this post, I came across a new approach that will allow access to internal structures without the need for using elevated permissions.&#160; This post will explore this new approach as well as build a new API for panning within the PivotViewer.</p>
<p><span id="more-396"></span>
<p>Before we get into panning within the PivotViewer, let’s take a look at this new approach.&#160; In the first post of this series, I discussed two approaches for getting access to the internals of the PivotViewer: visual tree hacking and using reflection.&#160; While reflection was a cleaner approach, it requires elevated permissions to access information about a class marked as internal.&#160; The problem with the visual tree approach is there needs to be part of the UI which indirectly exposes access to what you are trying to do.&#160; In the case of zooming, the zoom slider allowed us to build a zoom API by modifying its current value.&#160; However, the PivotViewer does not expose a UI control that will allow us to accomplish the same thing for panning. </p>
<p>Using the second approach, reflection, will require us to set the elevated trust permission on our application in order to use the API.&#160; While this is possible, it can certainly be a hurdle for some public implementations.&#160; So how do we overcome this situation?&#160; Well it turns out that binding to a property of an internal class does not fire off a security warning.&#160; That’s right boys and girls.&#160; As long as the class you are binding to supports INotifyPropertyChanged, we can bind to it and build an API around it.&#160; Of course, the best way to explain this is to show it in action.</p>
<p>To get things started, we are going to begin with the project from <a href="http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-zoom/">Hacking PivotViewer : Zoom</a>.&#160; You can download that project here: <a href="http://tonyc.me/GCkF1x">HackingPivotViewer_Zoom.zip</a></p>
<p>Just as we did with our zoom API, we are going to build our API with dependency properties and defining bindings by overriding the OnApplyTemplate method.&#160; For this project we need to create 3 dependency properties in our CustomPivotViewer class.&#160; The first will be the ZoomPanState.&#160; We will bind this property to the ZoomPanState object in the CollectionViewerViewModel.&#160; This is actually the object that controls the pan and the zoom.&#160; We will access the CollectionViewerViewModel through the visual tree as we did in the previous post.</p>
<p>The next two properties are the PanOffset and the TargetPanOffset.&#160; The PanOffset property binds to the Offset of the ZoomPanState.&#160; This is a Point object that defines the current pan offset.&#160; The TargetPanOffset binds to the TargetOffset property.&#160; Since PivotViewer uses zoom animations for everything, modifying the Offset property isn’t what you want to change.&#160; If you modify the TargetOffset, then the PivotViewer will create a smooth transition from its current Offset to the new TargetOffset.&#160; It is also important to note that we will create a two way binding for the PanTargetOffset.&#160; If you don’t, you will spend a while banging your head into your keyboard trying to figure out why values aren’t updating (or maybe that was just me). </p>
<pre class="brush: csharp;">public static readonly DependencyProperty ZoomPanStateProperty
    = DependencyProperty.Register(&quot;ZoomPanState&quot;,
                                typeof(object),
                                typeof(CustomPivotViewer), null);

public object ZoomPanState
{
    get { return GetValue(ZoomPanStateProperty); }
    set { SetValue(ZoomPanStateProperty, value); }
}

public static readonly DependencyProperty PanOffsetProperty
    = DependencyProperty.Register(&quot;PanOffset&quot;,
                                typeof(Point),
                                typeof(CustomPivotViewer), null);

public Point PanOffset
{
    get { return (Point)GetValue(PanOffsetProperty); }
    set { SetValue(PanOffsetProperty, value); }
}

public static readonly DependencyProperty TargetPanOffsetProperty
    = DependencyProperty.Register(&quot;TargetPanOffset&quot;,
                                typeof(Point),
                                typeof(CustomPivotViewer), null);

public Point TargetPanOffset
{
    get { return (Point)GetValue(TargetPanOffsetProperty); }
    set { SetValue(TargetPanOffsetProperty, value); }
}</pre>
<p>The next thing we need to do is to populate these values.&#160; As I mentioned above, this will be done via binding.&#160; By using Reflector, I was able to determine the structure of the CollectionViewViewModel class.&#160; The property we are interested in is the ZoomPanState.&#160; We will create a binding to our ZoomPanState dependency property.&#160; The two offest properties are mapped to properties of the ZoomPanState.&#160; It’s important to remember that this is an internal class, and therefore we shouldn’t be able to access the members.&#160; However, by using a little binding and understanding the structure of the class in question, we are able to expose access to the class and it’s properties.</p>
<pre class="brush: csharp;">public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    Grid templateChild = (Grid)base.GetTemplateChild(&quot;PART_Container&quot;);

    var coll = templateChild.Children[2] as Control;
    var viewModel = coll.Resources[&quot;ViewModel&quot;];

    var bind = new Binding(&quot;ZoomPanState&quot;);
    bind.Source = viewModel;
    SetBinding(ZoomPanStateProperty, bind);

    bind = new Binding(&quot;Offset&quot;);
    bind.Mode = BindingMode.TwoWay;
    bind.Source = ZoomPanState;
    SetBinding(PanOffsetProperty, bind);

    bind = new Binding(&quot;TargetOffset&quot;);
    bind.Mode = BindingMode.TwoWay;
    bind.Source = ZoomPanState;
    SetBinding(TargetPanOffsetProperty, bind);

}</pre>
<p>With that in mind, we will create a Pan method on our CustomPivotViewer that has two parameters: x and y.&#160; These parameters are going to work as you would expect.&#160; The x parameter will handle horizontal offsets and the y will handle the vertical.&#160; The method simply sets the PanTargetOffset to a new Point based on the current PanTargetOffset adjusted with the new values. </p>
<pre class="brush: csharp;">public void Pan(double x, double y)
{
    TargetPanOffset = new Point(PanOffset.X + x, PanOffset.Y + y);
}</pre>
<p>There are a couple of things to notice about the pan values.&#160; The values are based off of the total area of the collection based at its current zoom level.&#160; So the more you zoom in, the larger your canvas is.&#160; The second thing is that PivotViewer will do some bounds checking for you and not let you zoom pass the edge of the collection.&#160; Therefore, it’s not something you need to worry about writing code for.&#160; As of this writing, I haven’t located the current size of the collection.&#160; This would come in handy when you want to scale the amount you pan based on the current size. But alas, we can’t have everything that we want. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://tonychampion.net/blog/wp-content/uploads/2012/03/wlEmoticon-smile.png" /></p>
<p>Now let’s create a UI to test the new API.&#160; We will replace the header we added in the last post with a new one to examine the pan API.&#160; It consists of the current x and y offsets and four buttons (left, top, right, bottom). </p>
<pre class="brush: xml;">&lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot;&gt;
&lt;Grid.RowDefinitions&gt;
    &lt;RowDefinition Height=&quot;Auto&quot;/&gt;
    &lt;RowDefinition Height=&quot;*&quot;/&gt;
&lt;/Grid.RowDefinitions&gt;
&lt;StackPanel Orientation=&quot;Horizontal&quot; Height=&quot;50&quot;&gt;
    &lt;StackPanel.Resources&gt;
        &lt;Style TargetType=&quot;TextBlock&quot;&gt;
            &lt;Setter Property=&quot;VerticalAlignment&quot; Value=&quot;Center&quot;/&gt;
        &lt;/Style&gt;
    &lt;/StackPanel.Resources&gt;
    &lt;TextBlock Text=&quot;Offset X : &quot;/&gt;
    &lt;TextBlock Text=&quot;{Binding PanOffset.X,
                    ElementName=pViewer,
                    StringFormat=&#039;0.0&#039;}&quot;/&gt;
    &lt;TextBlock Text=&quot;   Offset Y : &quot;/&gt;
    &lt;TextBlock Text=&quot;{Binding PanOffset.Y,
                    ElementName=pViewer,
                    StringFormat=&#039;0.0&#039;}&quot;
                Margin=&quot;0,0,20,0&quot;/&gt;
    &lt;Button Content=&quot;Left&quot; Width=&quot;40&quot; Height=&quot;25&quot;
        x:Name=&quot;btnLeft&quot; Click=&quot;btnLeft_Click&quot;/&gt;
    &lt;Button Content=&quot;Up&quot; Width=&quot;40&quot; Height=&quot;25&quot;
        x:Name=&quot;btnUp&quot; Click=&quot;btnUp_Click&quot;/&gt;
    &lt;Button Content=&quot;Right&quot; Width=&quot;40&quot; Height=&quot;25&quot;
        x:Name=&quot;btnRight&quot; Click=&quot;btnRight_Click&quot;/&gt;
    &lt;Button Content=&quot;Down&quot; Width=&quot;40&quot; Height=&quot;25&quot;
        x:Name=&quot;btnDown&quot; Click=&quot;btnDown_Click&quot;/&gt;
&lt;/StackPanel&gt;
&lt;conv:CustomPivotViewer x:Name=&quot;pViewer&quot; Grid.Row=&quot;1&quot;&gt;
    &lt;pivot:PivotViewer.PivotProperties&gt;
        &lt;pivot:PivotViewerNumericProperty
Id=&quot;Value&quot;
Options=&quot;None&quot;
Binding=&quot;{Binding Value}&quot;/&gt;
        &lt;pivot:PivotViewerStringProperty
Id=&quot;Data1&quot;
Options=&quot;CanFilter,CanSearchText&quot; 

Binding=&quot;{Binding Data1}&quot;/&gt;
        &lt;pivot:PivotViewerStringProperty
Id=&quot;Color&quot;
Options=&quot;CanFilter,CanSearchText&quot;
Binding=&quot;{Binding Color}&quot;/&gt;
        &lt;pivot:PivotViewerDateTimeProperty
Id=&quot;Stamp&quot;
Options=&quot;CanFilter&quot;
Binding=&quot;{Binding Stamp}&quot;/&gt;
    &lt;/pivot:PivotViewer.PivotProperties&gt;
&lt;/conv:CustomPivotViewer&gt;</pre>
<p>The click event handlers make use of our new Pan method to set the offset in the correct directions. </p>
<pre class="brush: csharp;">private void btnDown_Click(object sender, RoutedEventArgs e)
{
    pViewer.Pan(0,100);
}

private void btnRight_Click(object sender, RoutedEventArgs e)
{
    pViewer.Pan(100,0);
}

private void btnUp_Click(object sender, RoutedEventArgs e)
{
    pViewer.Pan(0,-100);
}

private void btnLeft_Click(object sender, RoutedEventArgs e)
{
    pViewer.Pan(-100,0);
}</pre>
<p>Running the project your application should look like this. </p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/03/image1.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/03/image_thumb1.png" width="484" height="330" /></a></p>
<p>When you are zoomed out panning will not work, so don’t get discouraged.&#160; This is because the size of the collection canvas is equal to that of the available space.&#160; So trying to pan will hit the bounds checking that PivotViewer does.&#160; Once you zoom in, you should be able to pan around using the four buttons we added.&#160; You will also notice that PivotViewer makes nice smooth transitions when you pan.&#160; This is a result of using the TargetOffset and allowing PivotViewer to handle the actual transitions. </p>
<p>Well there you have it.&#160; We can now zoom and pan the PivotViewer.&#160; You can download the code for this project here: <a href="http://tonyc.me/GXLW0A">HackingPivotViewer_Pan.zip</a> </p>
<p>This series will continue as more customizations are created for the new PivotViewer.&#160; Make sure to check back for future updates.</p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/Y8A6U2YvROY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-pan/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<series:name><![CDATA[Hacking PivotViewer]]></series:name>
	<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-pan/</feedburner:origLink></item>
		<item>
		<title>Hacking PivotViewer : Zoom</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/w-07NCeGVHY/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-zoom/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 16:11:24 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[PivotViewer]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[pivotviewer]]></category>
		<category><![CDATA[silverlight 5]]></category>
		<category><![CDATA[Zoom]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=384</guid>
		<description><![CDATA[If you have been following my blog, you know that there are quite a few posts here on PivotViewer.&#160; If you haven’t seem them, you can find them all here: PivotViewer posts.&#160; The Silverlight 5 PivotViewer provides a laundry list of new features and enhancements, but there is still several areas that simply weren’t addressed [...]]]></description>
			<content:encoded><![CDATA[<p>If you have been following my blog, you know that there are quite a few posts here on PivotViewer.&#160; If you haven’t seem them, you can find them all here: <a href="http://tonychampion.net/blog/index.php/category/silverlight/pivotviewer-silverlight/">PivotViewer posts</a>.&#160; The Silverlight 5 PivotViewer provides a laundry list of new features and enhancements, but there is still several areas that simply weren’t addressed for one reason or another.</p>
<p>So that means it’s time to start taking matters in our own hands and start poking around under the hood.&#160; This is the first post in a new series, Hacking PivotViewer.&#160; This series will be a little different from some of the others, as it won’t be sequential.&#160; As I have time to tackle different road blocks, I will post the results to this series.&#160; Guess that means it’s time to get started.</p>
<p><span id="more-384"></span><br />
<h3>Methods of Hacking</h3>
<p>If you use Reflector on our good friend PivotViewer, you can quickly start to see what makes it tick.&#160; Unfortunately, most of the good stuff is labeled as “internal”, which means that we don’t have access to it.&#160; Correction, we are not supposed to have access to it.</p>
<p>When you run into this sort of situation, there are two different approaches you can take.&#160; The first is to use reflection.&#160; With reflection, you can gain access to an objects properties and methods (including private properties).&#160; This includes accessing internal objects as well.&#160; However, in Silverlight you have to run the application in ‘elevated trust’ mode in order to access internal classes.&#160; Otherwise you will receive a security violation error.</p>
<p>The second approach is to hack the visual tree.&#160; By gaining access to various parts of the visual tree, you can create hook points that will allow you to extend the PivotViewer.&#160; This was done quite a bit for the original PivotViewer.&#160; In fact, you can take a look at my CodePlex project that is centered around just that : <a href="http://pivotviewerlessons.codeplex.com/">PivotViewer Lessons</a>.</p>
<p>If given the choice, I would rather use reflection.&#160; You could create a public API that directly accessed the inner workings of PivotViewer.&#160; Unfortunately, the security requirements make that a non-starter for many projects.&#160; With that in mind, whenever possible, I will use the visual tree method.&#160; Fortunately, zooming is one area we can do this in.</p>
<h3>Exposing a Zoom API</h3>
<p>When tackling a problem like this, there are always several approaches that you can take.&#160; In fact, my first approach was scrapped in favor of the approach in this post.&#160; PivotViewer has some internal view models that we could use reflection to get access to and modify.&#160; However, the zoom slider control presents us an interesting entry point into the same view models.</p>
<p>By modifying the slider value we can change the zoom level and that is really all we need.&#160; The API for this project will consist of 3 values : minimum, maximum, and value.&#160; We will expose the min/max values simply to be a bit more informed.&#160; </p>
<p>The first thing we need to do is to get a PivotViewer project up and running.&#160; To speed things along, we will start with the project in my <a href="http://tonychampion.net/blog/index.php/2011/11/pv-basics-client-side-collections/">PivotViewer Basics: Client-Side Collections</a> post.&#160; You can download that project here: <a href="http://tonyc.me/tUL3PR">PVB01_ClientSideCreations.zip</a>.</p>
<p>Now that we have a working sample project, we can get to work.&#160; In order to encapsulate the code, we are going to create a new class the inherits the PivotViewer.&#160; The first thing we are going to do is to add 3 dependency properties.&#160; The reason we are using dependency properties is to open up binding possibilities.&#160; If you would prefer, you could create simple properties in place of these.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> CustomPivotViewer : PivotViewer
{
    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DependencyProperty ZoomMinProperty
        = DependencyProperty.Register(<span class="str">&quot;ZoomMinimum&quot;</span>,
                                        <span class="kwrd">typeof</span>(<span class="kwrd">double</span>),
                                        <span class="kwrd">typeof</span>(CustomPivotViewer),
                                        <span class="kwrd">null</span>);

    <span class="kwrd">public</span> <span class="kwrd">double</span> ZoomMinimum
    {
        get { <span class="kwrd">return</span> (<span class="kwrd">double</span>)GetValue(ZoomMinProperty); }
        set { SetValue(ZoomMinProperty, <span class="kwrd">value</span>); }
    }

    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DependencyProperty ZoomMaxProperty
        = DependencyProperty.Register(<span class="str">&quot;ZoomMaximum&quot;</span>,
                                        <span class="kwrd">typeof</span>(<span class="kwrd">double</span>),
                                        <span class="kwrd">typeof</span>(CustomPivotViewer),
                                        <span class="kwrd">null</span>);

    <span class="kwrd">public</span> <span class="kwrd">double</span> ZoomMaximum
    {
        get { <span class="kwrd">return</span> (<span class="kwrd">double</span>)GetValue(ZoomMaxProperty); }
        set { SetValue(ZoomMaxProperty, <span class="kwrd">value</span>); }
    }

    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DependencyProperty ZoomValueProperty
        = DependencyProperty.Register(<span class="str">&quot;ZoomValue&quot;</span>,
                                        <span class="kwrd">typeof</span>(<span class="kwrd">double</span>),
                                        <span class="kwrd">typeof</span>(CustomPivotViewer),
                                        <span class="kwrd">null</span>);

    <span class="kwrd">public</span> <span class="kwrd">double</span> ZoomValue
    {
        get { <span class="kwrd">return</span> (<span class="kwrd">double</span>)GetValue(ZoomValueProperty); }
        set { SetValue(ZoomValueProperty, <span class="kwrd">value</span>); }
    }
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>When a control’s UI gets generated in Silverlight, a method OnApplyTemplate is called.&#160; You can override this method and this creates a great place to tie into elements of the visual tree.&#160; The reason is, prior to this point, the visual tree elements do not exist.&#160; </p>
<p>Let’s add an override of the OnApplyTemplate method.&#160; Once the base control has created the visual tree, we can now find the zoom slider.&#160; This is accomplished by using the GetTemplateChild method.&#160; The method will return the Slider control that is used for zooming.&#160; We will bind the Minimum, Maximum, and Value properites of the slider control to our 3 new dependency properties.</p>
<p>&#160;</p>
<p><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnApplyTemplate()
{
    <span class="kwrd">base</span>.OnApplyTemplate();

    Slider templateChild1
         = (Slider)<span class="kwrd">base</span>.GetTemplateChild(<span class="str">&quot;PART_ZoomSlider&quot;</span>);
    var binding = <span class="kwrd">new</span> Binding(<span class="str">&quot;Minimum&quot;</span>);
    binding.Source = templateChild1;
    SetBinding(ZoomMinProperty, binding);
    binding = <span class="kwrd">new</span> Binding(<span class="str">&quot;Maximum&quot;</span>);
    binding.Source = templateChild1;
    SetBinding(ZoomMaxProperty, binding);
    binding = <span class="kwrd">new</span> Binding(<span class="str">&quot;Value&quot;</span>);
    binding.Source = templateChild1;
    binding.Mode = BindingMode.TwoWay;
    SetBinding(ZoomValueProperty, binding);

}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>The last thing we are going to add is a method to allow us to increment the zoom value.&#160; You can accomplish this my changing the ZoomValue directly, but this way we can handle increments as well.&#160; The method does a little bounds checking and then adds the increment value to Value of the zoom slider.&#160; Positive values will zoom in and negative values will zoom out.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Zoom(<span class="kwrd">int</span> val)
{
    var newVal = ZoomValue + val;
    ZoomValue = Math.Min(ZoomMaximum,
        Math.Max(ZoomMinimum, newVal));
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Armed with our new custom PivotViewer, let’s modify MainPage.xaml to use the it instead of the original version. </p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">conv:CustomPivotViewer</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;pViewer&quot;</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewer.PivotProperties</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerNumericProperty</span>
    <span class="attr">Id</span><span class="kwrd">=&quot;Value&quot;</span>
    <span class="attr">Options</span><span class="kwrd">=&quot;None&quot;</span>
    <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Value}&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerStringProperty</span>
    <span class="attr">Id</span><span class="kwrd">=&quot;Data1&quot;</span>
    <span class="attr">Options</span><span class="kwrd">=&quot;CanFilter,CanSearchText&quot;</span> 

    <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Data1}&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerStringProperty</span>
    <span class="attr">Id</span><span class="kwrd">=&quot;Color&quot;</span>
    <span class="attr">Options</span><span class="kwrd">=&quot;CanFilter,CanSearchText&quot;</span>
    <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Color}&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerDateTimeProperty</span>
    <span class="attr">Id</span><span class="kwrd">=&quot;Stamp&quot;</span>
    <span class="attr">Options</span><span class="kwrd">=&quot;CanFilter&quot;</span>
    <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Stamp}&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">pivot:PivotViewer.PivotProperties</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">conv:CustomPivotViewer</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>And that is really all there is to is.&#160; Of course, you probably want to make sure this actually works, right?&#160; Well let’s do just that.&#160; Below is a modification of the MainPage that adds a stack panel above the CustomPivotViewer.&#160; It will display the min, max, and value of the current zoom.&#160; It also contains two buttons, “In” and “Out”.&#160; Care to guess what these are going to do?</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;LayoutRoot&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;White&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Grid.RowDefinitions</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">=&quot;Auto&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">=&quot;*&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Grid.RowDefinitions</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">Orientation</span><span class="kwrd">=&quot;Horizontal&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;50&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">StackPanel.Resources</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;TextBlock&quot;</span><span class="kwrd">&gt;</span>
             <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;VerticalAlignment&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Center&quot;</span><span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">StackPanel.Resources</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;Zoom Minimum : &quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;{Binding ZoomMinimum,
                            ElementName=pViewer,
                            StringFormat='0.0'}&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;   Maximum : &quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;{Binding ZoomMaximum,
                            ElementName=pViewer,
                            StringFormat='0.0'}&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;   Value : &quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;{Binding ZoomValue,
                            ElementName=pViewer,
                            StringFormat='0.0'}&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;30&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">=&quot;In&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;30&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;25&quot;</span>
                <span class="attr">x:Name</span><span class="kwrd">=&quot;btnIn&quot;</span> <span class="attr">Click</span><span class="kwrd">=&quot;btnIn_Click&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">=&quot;Out&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;30&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;25&quot;</span>
                <span class="attr">x:Name</span><span class="kwrd">=&quot;btnOut&quot;</span> <span class="attr">Click</span><span class="kwrd">=&quot;btnOut_Click&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">conv:CustomPivotViewer</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;pViewer&quot;</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewer.PivotProperties</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerNumericProperty</span>
        <span class="attr">Id</span><span class="kwrd">=&quot;Value&quot;</span>
        <span class="attr">Options</span><span class="kwrd">=&quot;None&quot;</span>
        <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Value}&quot;</span><span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerStringProperty</span>
        <span class="attr">Id</span><span class="kwrd">=&quot;Data1&quot;</span>
        <span class="attr">Options</span><span class="kwrd">=&quot;CanFilter,CanSearchText&quot;</span> 

        <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Data1}&quot;</span><span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerStringProperty</span>
        <span class="attr">Id</span><span class="kwrd">=&quot;Color&quot;</span>
        <span class="attr">Options</span><span class="kwrd">=&quot;CanFilter,CanSearchText&quot;</span>
        <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Color}&quot;</span><span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerDateTimeProperty</span>
        <span class="attr">Id</span><span class="kwrd">=&quot;Stamp&quot;</span>
        <span class="attr">Options</span><span class="kwrd">=&quot;CanFilter&quot;</span>
        <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Stamp}&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">pivot:PivotViewer.PivotProperties</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">conv:CustomPivotViewer</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>The last thing we need to do is to implement the Click handlers for the two buttons.&#160; Both simply call our Zoom method we created to increment the zoom level.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> btnIn_Click(<span class="kwrd">object</span> sender, RoutedEventArgs e)
{
    pViewer.Zoom(1);
}

<span class="kwrd">private</span> <span class="kwrd">void</span> btnOut_Click(<span class="kwrd">object</span> sender, RoutedEventArgs e)
{
    pViewer.Zoom(-1);
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Now if we run the project, you should get something that looks like this:</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/03/image.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/03/image_thumb.png" width="550" height="338" /></a></p>
<p>The buttons will allow you to zoom in and out.&#160; PivotViewer handles all of the nice smooth transitions for you and everything.&#160; If you want to zoom out to the default view, you just need to set ZoomValue to 1.0.</p>
<p>You will start to see more of these hacks over the next few months.&#160; I am working on a Silverlight 5 version of PivotViewer Lessons to help centralize all of these changes.</p>
<p>You can download the completed project here : <a href="http://tonyc.me/GCkF1x">HackingPV_Zoom.zip</a></p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/w-07NCeGVHY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-zoom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Hacking PivotViewer]]></series:name>
	<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/03/hacking-pivotviewer-zoom/</feedburner:origLink></item>
		<item>
		<title>PivotViewer Multi-Valued Properties</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/_uIe05rIB3E/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/02/pivotviewer-multi-valued-properties/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 19:41:11 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[PivotViewer]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[pivotviewer]]></category>
		<category><![CDATA[silverlight 5]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=380</guid>
		<description><![CDATA[Defining properties in the new PivotViewer is rather straight forward, but I was recently asked about defining a multi-valued property.&#160; In the original PivotViewer, the CXML item would simply contain multiple entries for a given property and the PivotViewer would do the rest.&#160; Fortunately, PivotViewer still handles most of the details for us, with a [...]]]></description>
			<content:encoded><![CDATA[<p>Defining properties in the new PivotViewer is rather straight forward, but I was recently asked about defining a multi-valued property.&#160; In the original PivotViewer, the CXML item would simply contain multiple entries for a given property and the PivotViewer would do the rest.&#160; Fortunately, PivotViewer still handles most of the details for us, with a minor catch.</p>
<p><span id="more-380"></span>
<p>Mapping a multi-valued list to PivotViewer is basically the same as a single valued property.&#160; The same property types apply and the actual definition is identical.</p>
<p>For this project, we are going to borrow the sample project from the <a href="http://tonychampion.net/blog/index.php/series/pivotviewer-basics/">PivotViewer Basics Series</a>.&#160; You can get the base project from the Client-Side Collections here : <a href="http://tonyc.me/tUL3PR">PVB01_ClientSideCreation.zip</a>.</p>
<p>Just to get a base-line of where we are starting from, you can run the project and you should see a collection of colored trading cards with some simplistic properties.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image9.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb9.png" width="459" height="332" /></a></p>
<p>If you take a look at our XAML in the MainPage, we have a DateTime property defined as Stamp.&#160; If you look at the DemoItem there is a BuildData() method that generates our data for the collection, which includes a date for our Stamp property.</p>
<p>What if we wanted to track multiple dates for this property?&#160; Since that is what this post is about, it seems a relevant question.&#160; From a XAML and PivotViewer point of view, we don’t have to make any changes.&#160; PivotViewer will accept a single DateTime value or a collection of DateTime values.</p>
<p>With that taken care of, we can now shift our focus to the DemoItem class itself.&#160; The first thing we need to do is change the Shift property to a collection.&#160; For simplicity we will create a List&lt;DateTime&gt;.&#160; However, if you create a collection that implements the INotifyCollectionChanged interface, such as an ObservableCollection, PivotViewer will update the item whenever that collection changes.&#160; Since we are created a static list when the object is created, a List&lt;&gt; will work just fine in this example.</p>
<p>The next step is to modify the BuildData() method to populate our Stamp property with a collection of DateTimes.&#160; Here is the modified portions of our DemoItem class.</p>
<pre class="csharpcode">    <span class="kwrd">public</span> <span class="kwrd">class</span> DemoItem : INotifyPropertyChanged
    {

        ...

        <span class="kwrd">private</span> List&lt;DateTime&gt; _stamp;
        <span class="kwrd">public</span> List&lt;DateTime&gt; Stamp
        {
            get { <span class="kwrd">return</span> _stamp; }
            set
            {
                _stamp = <span class="kwrd">value</span>;
                NotifyProperty(<span class="str">&quot;Stamp&quot;</span>);
            }
        }

        <span class="kwrd">public</span> <span class="kwrd">static</span> ObservableCollection&lt;DemoItem&gt; BuildData()
        {

             ...
                itm.Stamp = <span class="kwrd">new</span> List&lt;DateTime&gt;()
                            {DateTime.Now.AddDays(-1 * i),
                             DateTime.Now.AddDays(-1 * 5 - 20)};

             ...
        }

     ...

    }</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image10.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb10.png" width="372" height="295" /></a></p>
<p>Now if we run our project and select an item, you will see that the Stamp property in the detail pane has multiple values in it.&#160; Seems simple enough, right? With your application running, change the sort property to Stamp. Oops, seems we get the following error:</p>
<blockquote>
<p><em>“Failed to compare two elements in the array.”</em></p>
</blockquote>
<p>The reason for this error is that PivotViewer is unable to sort the items based on a List&lt;DateTime&gt; data type.&#160; If you think about it, it makes sense.&#160; If you have two lists of DateTime, which one comes first?&#160; It really depends on your usage of it and therefore we will need to write some code.</p>
<p>To accomplish this we are going to create a new class : DateTimeList.&#160; The class will inherit the List&lt;DateTime&gt; as well as implement the IComparable interface.&#160; The IComparable interface adds a single method to our class, CompareTo.&#160; For our case, we are going to sort based on the first DateTime in the list.&#160; Our new class will look like this:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> DateTimeList : List&lt;DateTime&gt;, IComparable
{

    <span class="kwrd">public</span> <span class="kwrd">int</span> CompareTo(<span class="kwrd">object</span> obj)
    {
        <span class="kwrd">return</span> <span class="kwrd">this</span>[0].CompareTo((obj <span class="kwrd">as</span> DateTimeList)[0]);
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Now let’s change our DemoItem to use our new class instead of the original List&lt;DateTime&gt;.</p>
<p>&#160;</p>
<pre class="csharpcode">    <span class="kwrd">public</span> <span class="kwrd">class</span> DemoItem : INotifyPropertyChanged
    {

        ...

        <span class="kwrd">private</span> DateTimeList _stamp;
        <span class="kwrd">public</span> DateTimeList Stamp
        {
            get { <span class="kwrd">return</span> _stamp; }
            set
            {
                _stamp = <span class="kwrd">value</span>;
                NotifyProperty(<span class="str">&quot;Stamp&quot;</span>);
            }
        }

        <span class="kwrd">public</span> <span class="kwrd">static</span> ObservableCollection&lt;DemoItem&gt; BuildData()
        {

            ...
                itm.Stamp = <span class="kwrd">new</span> DateTimeList
                  {DateTime.Now.AddDays(-1 * i),
                  DateTime.Now.AddDays(-1 * 5 - 20)};

            ...
        }

    }</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Rerunning our application, we can now select Stamp as the sort property and PivotViewer will sort based on our definition.&#160; It is worth noting that if you did not have the “CanFilter” option set on the Stamp PivotProperty, it would not be necessary to create a new collection object.&#160; </p>
<p>The completed project of for this post can be found here: <a href="http://tonychampion.net/blog/wp-content/uploads/Projects/PV_MultiValued.zip">PV_MultiValued.zip</a></p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/_uIe05rIB3E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/02/pivotviewer-multi-valued-properties/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/02/pivotviewer-multi-valued-properties/</feedburner:origLink></item>
		<item>
		<title>MVPChat : A PivotViewer Use Case</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/OlBroiQJP2U/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/02/mvpchat-a-pivotviewer-use-case/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 18:33:06 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[PivotViewer]]></category>
		<category><![CDATA[MVPChat]]></category>
		<category><![CDATA[pivotviewer]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=373</guid>
		<description><![CDATA[For the past year, the Microsoft MVP Program has been holding Twitter chats.&#160; The idea is that for a given date/time (usually a 1-2 hr window), you could be involved in a group conversation by following the #mvpchat hash tag.&#160; During the first conversation, as I watched the feed blow by at amazing speed, I [...]]]></description>
			<content:encoded><![CDATA[<p>For the past year, the Microsoft MVP Program has been holding Twitter chats.&#160; The idea is that for a given date/time (usually a 1-2 hr window), you could be involved in a group conversation by following the #mvpchat hash tag.&#160; During the first conversation, as I watched the feed blow by at amazing speed, I realized that PivotViewer would offer a unique look into this type of data.&#160; So within a couple of weeks of the first event, MVPChat (<a href="http://mvpchat.net">http://mvpchat.net</a>) was born.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image6.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb6.png" width="368" height="266" /></a></p>
<p><span id="more-373"></span>
<p>Since then, we have recorded five separate events and they are all still available online.&#160; With each event, a newer version was created and the application continues to grow.&#160; With the last event, I was able to roll out a Silverlight 5 version using the newest PivotViewer.&#160; The latest version is actually an early beta of an upcoming product that I will be announcing soon.&#160; I have received a lot of interest in real-world examples of the PivotViewer, so I thought I would take some time to walk thru MVPChat and show PivotViewer in action.</p>
<h3>Analyzing the Data</h3>
<p>If you have heard me give a talk about PivotViewer, then you have heard me say that the key to creating a successful PivotViewer is to truly understand the data. (If you haven’t heard me talk on PivotViewer, then why not? <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/wlEmoticon-smile1.png" /> ).&#160; That was the case here as well.&#160; The first attempt tracked very little data points.&#160; It was nothing more than the basics: author and date/time of post.&#160; While that was useful to a degree, it wasn’t all that useful.&#160; The next attempt really focused on the data in each Tweet.&#160; We pulled out hash tags, mentions, sources, and looked for a list of key words.&#160; While better, it simply didn’t get us where we needed to be.&#160; </p>
<p>The MVP Chat had a unique feature that really made this turn on it’s head.&#160; The moderator would throw out questions, marked with a #Q1,#Q2, etc.&#160; Then participants could respond using that same hash tag or some variant (which made data mining difficult to say the least).&#160; However, by adding a Question property to the PivotViewer, we could start to drill down into micro conversations with the entire event itself.&#160; This not only made the application fun to use to dig thru the data, but it is now useful from an informational perspective by allowing you to pull inter-related information.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image7.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb7.png" width="331" height="219" /></a></p>
<h3>Designing the Trading Cards</h3>
<p>Now I have to admit, this is still a work in progress.&#160; However, if you take a look at the original version using PivotViewer v1, which is still live at <a href="http://mvpchat.championds.com">http://mvpchat.championds.com</a>, you will hopefully agree we have come a long way.</p>
<p>The first thing you will notice is that there is actually two cards being used.&#160; The smallest card is simply the thumbnail of the author.&#160; The larger card has the tweet itself, a date/time stamp, and some author information in it.&#160; An interesting challenge was the background.&#160; In an attempt to use the author’s profile background color to distinguish one card from another, I came across the problem of using appropriate colors of the Tweet box.&#160; The default is a white background, however, if the user’s background color was anywhere close to white, it all blended together. </p>
<p>After doing some research on color brightness and using the formula at <a title="http://maestric.com/doc/color_brightness_difference_calculator" href="http://maestric.com/doc/color_brightness_difference_calculator">http://maestric.com/doc/color_brightness_difference_calculator</a>, I came up with a plan to test the color brightness and change the Tweet window accordingly.&#160; While not 100% of where I want it to be, it has allowed me to dynamically change the color based on the author’s profile color.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image8.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb8.png" width="244" height="243" /></a></p>
<h3></h3>
<h3>Customizing the PivotViewer</h3>
<p>Now I couldn’t very well simply leave the PivotViewer alone, could I?&#160; That just doesn’t seem right for some reason.&#160; Any while again, not exactly finished, I’ve been happy with the major item of focus in my customizations.</p>
<p>The first minor change I did was to remove the detail pane.&#160; In this situation, there isn’t much that a detail pane could offer.&#160; That might actually change in future iterations, but for now, it was simply removed.</p>
<p>Then I moved on to my major challenge, the item adorner.&#160; I wanted to create a full card adorner that would allow the user to interact directly with the trading card.&#160; I won’t go into the details of how I accomplished this here, but you can read about it on my <a href="http://tonychampion.net/blog/index.php/2012/02/pivotviewer-basics-custom-item-adorners/" target="_blank">PivotViewer Basics: Custom Item Adorners</a> post.&#160; After several unsuccessful attempts and a few choice words, I was able to get the basic concept working.&#160; </p>
<p>If you select an item in the PivotViewer, the first thing you will notice is a “Follow” button shows up that will redirect you to Twitter to allow you to follow that user.&#160; However, if you look more closely, you will notice that all of the mentions, hash tags, and the author’s handle are all links.&#160; Clicking on one of the links will change the filter and allow you to navigate around the PivotViewer.&#160; While I have plans for extending this adorner in the future, I was fairly happy with the results to this point.</p>
<h3>The End Results</h3>
<p>I would be lying if I told you I didn’t bump into any issues along the way.&#160; In fact, all of the issues I ran across I either have or will write about on the blog.&#160; However, overall I think the new Silverlight 5 PivotViewer stood it’s ground rather well.&#160; The new dynamic features really make a difference in building real world solutions.</p>
<p>As far as 3rd party controls, I only used one.&#160; The transitions between pages in the navigation are handled with <a href="http://www.telerik.com/products/silverlight/controls/transition.aspx" target="_blank">Telerik’s Transition control</a>.&#160; I have used Telerik’s controls on several projects and I have been really impressed with how they are written and perform.</p>
<h3>Next Steps…</h3>
<p>You might remember me mentioning, at the beginning of this post, that this application is an early beta of a new product coming.&#160; And since it is, I was wondering if you could help me out.&#160; I have a few short (6 question) survey that I have posted in order to get some feedback on MVPChat.&#160; I would appreciate all of the feedback that I could get and wonder if you would mind filling it out after you played with MVPChat for a minute?</p>
<p>Below are the links to the application and the survey as well.&#160; I have several more posts queued up on PivotViewer, Silverlight, and Win8.&#160; Until then… Happy Pivoting…</p>
<p>Website : <a href="http://mvpchat.net">http://mvpchat.net</a></p>
<p>Survey: <a title="http://tonyc.me/xuAXJd" href="http://tonyc.me/xuAXJd">http://tonyc.me/xuAXJd</a></p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/OlBroiQJP2U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/02/mvpchat-a-pivotviewer-use-case/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/02/mvpchat-a-pivotviewer-use-case/</feedburner:origLink></item>
		<item>
		<title>Silverlight ComboBoxItem IsEnabled, SL5 Style</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/2jckaGq-RMQ/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/02/silverlight-comboboxitem-isenabled-sl5-style/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 04:10:29 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[ComboBox]]></category>
		<category><![CDATA[ComboBoxItem]]></category>
		<category><![CDATA[silverlight 5]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=364</guid>
		<description><![CDATA[I was recently working with another developer on a ComboBox, where he needed to be able to disable certain items in the ComboBox (aka make them non-selectable).&#160; Having been a while since I looked at it, all I could remember was it was not as easy as it should be.&#160; In coming up with a [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently working with another developer on a ComboBox, where he needed to be able to disable certain items in the ComboBox (aka make them non-selectable).&#160; Having been a while since I looked at it, all I could remember was it was not as easy as it should be.&#160; In coming up with a solution, we realized that Silverlight 5 makes this rather easy.</p>
<p><span id="more-364"></span>
<p>So why would we want to disable a ComboBoxItem in the first place?&#160; If you can disable individual items in a ComboBox, then you can still present the user with all of the available data, without making them all an actionable option.&#160; In our example we are going to create a product list ComboBox.&#160; In this scenario we want the user to see all of the products that we carry, but they should only be able to select the items that we currently have in stock.</p>
<p>To start off our project, we will create a new Silverlight 5 Application.&#160; Plain and simple with no bells and whistles.</p>
<p>The first thing we need to do is to create our data object.&#160; For this demo we will only have two properties, Name and IsAvailable.&#160; Our class will also have a static method that will return our test data.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Product
{
    <span class="kwrd">public</span> <span class="kwrd">string</span> Name { get; set; }
    <span class="kwrd">public</span> <span class="kwrd">bool</span> IsAvailable { get; set; }

    <span class="kwrd">public</span> <span class="kwrd">static</span> IEnumerable&lt;Product&gt; GetProducts()
    {
        <span class="kwrd">return</span> <span class="kwrd">new</span> List&lt;Product&gt;()
                    {
                        <span class="kwrd">new</span> Product() { Name=<span class="str">&quot;Saw&quot;</span> ,
                            IsAvailable = <span class="kwrd">true</span>},
                        <span class="kwrd">new</span> Product() { Name=<span class="str">&quot;Hammer&quot;</span> ,
                            IsAvailable = <span class="kwrd">true</span>},
                        <span class="kwrd">new</span> Product() { Name=<span class="str">&quot;Clamp&quot;</span> ,
                            IsAvailable = <span class="kwrd">false</span>},
                        <span class="kwrd">new</span> Product() { Name=<span class="str">&quot;Level&quot;</span> ,
                            IsAvailable = <span class="kwrd">true</span>},
                    };
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Now we can create our testing UI.&#160; It will be a simple Grid containing our CombBox and a few TextBlocks.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">Width</span><span class="kwrd">=&quot;Auto&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;Auto&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span>
      <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Center&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Grid.ColumnDefinitions</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">ColumnDefinition</span> <span class="attr">Width</span><span class="kwrd">=&quot;Auto&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">ColumnDefinition</span> <span class="attr">Width</span><span class="kwrd">=&quot;Auto&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Grid.ColumnDefinitions</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Grid.RowDefinitions</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">=&quot;Auto&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">=&quot;Auto&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Grid.RowDefinitions</span><span class="kwrd">&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;Combo Box : &quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span><span class="kwrd">=&quot;Selected Item : &quot;</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">ComboBox</span>
            <span class="attr">x:Name</span><span class="kwrd">=&quot;cbTest&quot;</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">=&quot;1&quot;</span>
            <span class="attr">DisplayMemberPath</span><span class="kwrd">=&quot;Name&quot;</span> <span class="kwrd">/&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">=&quot;1&quot;</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">=&quot;1&quot;</span>
        <span class="attr">Text</span><span class="kwrd">=&quot;{Binding SelectedItem.Name, ElementName=cbTest}&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you look at our ComboBox, we will be displaying the Product Name property.&#160; The last TextBlock maps its Text property to the Name property of the SelectedItem of our ComboBox.&#160; Fairly straight forward, right?</p>
<p>Just for completion sake, I added some Style resources to the UserControl.Resources in order to make the project a bit more readable.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;TextBlock&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;FontSize&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;22&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Margin&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;0,10,20,0&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;ComboBox&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;FontSize&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;22&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Height&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;30&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Width&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;150&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you run the project, you should see something like this :</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image3.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb3.png" width="374" height="140" /></a></p>
<p>The last thing we need to add is come data.&#160; In order to do that, let’s add the following line to our MainPage code behind:</p>
<pre class="csharpcode">cbTest.ItemsSource = Product.GetProducts();</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Running our project again, you should now have data.&#160; Selecting an item should update the Selected Item text.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image4.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb4.png" width="381" height="141" /></a></p>
<p>Now the we have our project set up, how can we disable individual items?&#160; The default Item container for a CombBox is the CombBoxItem.&#160; That means that for every item that you create, regardless if you are using the DisplayMemberPath or a custom ItemTemplate, is set inside a ComboBoxItem.&#160; It just so happens that the ComboBoxItem object has an IsEnabled property that we can use to enable/disable the items.</p>
<p>Prior to Silverlight 5, there were several ways of attacking this problem, however Silverlight 5 offers a much simpler approach.&#160; On day 6 of my <a href="http://tonychampion.net/blog/index.php/series/12-days-of-silverlight/" target="_blank">12 Days of Silverlight series</a> I talked about the new Silverlight 5 feature of <a href="http://tonychampion.net/blog/index.php/2011/12/6th-day-of-silverlight-binding-in-style-setters/" target="_blank">Binding in Style setters</a>.&#160; So how about we show this new feature in action?</p>
<p>We can use the new binding feature to make using the IsEnabled property a snap.&#160; Let’s add the following Style settings to our User.Resources.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;ComboBoxItem&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;IsEnabled&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;{Binding IsAvailable}&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Now the IsEnabled property of the ComboBoxItem will be triggered off of our IsAvailable Product property.&#160; Yep, it’s that easy.&#160; Let’s rerun our application and see what we have.&#160; If you expand the ComboBox, you will notice that the Clamp item is greyed out and you cannot select it.&#160; And you thought you wouldn’t use binding in Style setters.&#160; Tisk tisk…</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image5.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb5.png" width="357" height="195" /></a></p>
<p>This post was really about two things.&#160; The first was to solve the direct problem of disabling items in your ComboBox.&#160; The second was to give a real life example of using the binding in Style setters.</p>
<p>You can download the code for the project : <a href="http://tonychampion.net/blog/wp-content/uploads/Projects/SL5ComboBoxItemEnabled.zip" target="_blank">SL5ComboBoxItemEnabled.zip</a></p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/2jckaGq-RMQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/02/silverlight-comboboxitem-isenabled-sl5-style/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/02/silverlight-comboboxitem-isenabled-sl5-style/</feedburner:origLink></item>
		<item>
		<title>PivotViewer Basics: Custom Item Adorners</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/bXEHEEDvYlY/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/02/pivotviewer-basics-custom-item-adorners/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 19:26:01 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[PivotViewer]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[item adorners]]></category>
		<category><![CDATA[pivotviewer]]></category>
		<category><![CDATA[silverlight 5]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=354</guid>
		<description><![CDATA[Well we are coming to the end of the PivotViewer Basics series.&#160; To round it out, I thought I would continue on with the last post which discussed Basic Item Adorners.&#160; In that post we looked at implementing the custom actions that you found in the first PivotViewer.&#160; This post will look at taking it [...]]]></description>
			<content:encoded><![CDATA[<p>Well we are coming to the end of the <a href="http://tonychampion.net/blog/index.php/series/pivotviewer-basics/" target="_blank">PivotViewer Basics series</a>.&#160; To round it out, I thought I would continue on with the last post which discussed <a href="http://tonychampion.net/blog/index.php/2012/01/pivotviewer-basics-basic-item-adorners/" target="_blank">Basic Item Adorners</a>.&#160; In that post we looked at implementing the custom actions that you found in the first PivotViewer.&#160; This post will look at taking it one step further and look at what it takes to build our own item adorners.&#160; </p>
<p><span id="more-354"></span><br />
<h3>Basic Border Adorner</h3>
<p>As we have done in the rest of the series, we will start with the code from the first post in this series, <a href="http://tonychampion.net/blog/index.php/2011/11/pv-basics-client-side-collections/" target="_blank">Client-Side Collections</a>.&#160; You can download that project here : <a href="http://tonyc.me/tUL3PR" target="_blank">PVB01_ClientSideCreation.zip</a>.</p>
<p>We are going to start the first example with the basics.&#160; Once you set your own item adorner, you will lose the very basic adorner that comes out of the box, the highlight border.&#160; If you need to refresh your memory, run the project above and you will see that every time you mouse over or select an item it is highlighted with a light blue border around it.</p>
<p>If you dig into the PivotViewer XAML you will find that there is actually a bug here.&#160; That light blue border is actually the selected border.&#160; The mouse over border is a different color.&#160; The item adorner defines a couple visual states in the group “ItemStates”.&#160; The selected border is driven off of the “IsSelected” state.&#160; However, the “IsSelected” state also fires on a simple mouse over, even if the items itself is not selected.&#160; Since the selected border sits on top of the mouse over border, you will always see the selected one.&#160; What does this mean for us?&#160; It simply means we are not going to use the “IsSelected” visual state to drive our adorner.</p>
<p>Now that we have that out of the way, let’s create our item adorner.&#160; If you read the last post , you might recall that the PivotViewer has a <strong>ItemAdornerStyle</strong> where we implemented the <strong>PivotViewerBasicItemAdorner</strong>.&#160; Our first item adorner is going to look very similar, except we are going to remove the basic item adorner.&#160; In fact, to show a point, it is going to look rather blank.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;basicAdorner&quot;</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;pivot:PivotViewerItemAdorner&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Template&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">ControlTemplate</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">Background</span><span class="kwrd">=&quot;Transparent&quot;</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">ControlTemplate</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>To assign our adorner to the PivotViewer, we can set the ItemAdornerStyle property to our new style.</p>
<pre class="csharpcode">&lt;pivot:PivotViewer x:Name=<span class="str">&quot;pViewer&quot;</span>
ItemAdornerStyle=<span class="str">&quot;{StaticResource basicAdorner}&quot;</span>&gt;
   ...
&lt;/pivot:PivotViewer&gt;</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you run the project you will see that it’s not very exciting.&#160; In fact, you will notice that the highlight border is missing completely.&#160; However, that’s good.&#160; The gives us a nice blank canvas to start from.&#160; In order to add our highlight border back, we are going to add two <strong>Border</strong> objects to our <strong>Grid</strong>.&#160; The first one will be visible when we you mouse over an item.&#160; The second will show when the item is selected.&#160; By adding the selected <strong>Border</strong> second, it will hide the mouse over one when an item is selected and the mouse is over it.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;basicAdorner&quot;</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;pivot:PivotViewerItemAdorner&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Template&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">ControlTemplate</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">Background</span><span class="kwrd">=&quot;Transparent&quot;</span><span class="kwrd">&gt;</span>
                    <span class="kwrd">&lt;</span><span class="html">VisualStateManager.VisualStateGroups</span><span class="kwrd">&gt;</span>
                        <span class="kwrd">&lt;</span><span class="html">VisualStateGroup</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;CommonStates&quot;</span><span class="kwrd">&gt;</span>
                            <span class="kwrd">&lt;</span><span class="html">VisualState</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Normal&quot;</span><span class="kwrd">/&gt;</span>
                            <span class="kwrd">&lt;</span><span class="html">VisualState</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;MouseOver&quot;</span><span class="kwrd">&gt;</span>
                                <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
                                   <span class="kwrd">&lt;</span><span class="html">DoubleAnimationUsingKeyFrames</span>
                   <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;(UIElement.Opacity)&quot;</span>
                       <span class="attr">Storyboard</span>.<span class="attr">TargetName</span><span class="kwrd">=&quot;ButtonBorder&quot;</span><span class="kwrd">&gt;</span>
                                 <span class="kwrd">&lt;</span><span class="html">EasingDoubleKeyFrame</span> <span class="attr">KeyTime</span><span class="kwrd">=&quot;0&quot;</span>
                                        <span class="attr">Value</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span>
                                 <span class="kwrd">&lt;/</span><span class="html">DoubleAnimationUsingKeyFrames</span><span class="kwrd">&gt;</span>
                                <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
                            <span class="kwrd">&lt;/</span><span class="html">VisualState</span><span class="kwrd">&gt;</span>
                            <span class="kwrd">&lt;</span><span class="html">VisualState</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Disabled&quot;</span><span class="kwrd">/&gt;</span>
                        <span class="kwrd">&lt;/</span><span class="html">VisualStateGroup</span><span class="kwrd">&gt;</span>
                        <span class="kwrd">&lt;</span><span class="html">VisualStateGroup</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;ItemStates&quot;</span><span class="kwrd">&gt;</span>
                            <span class="kwrd">&lt;</span><span class="html">VisualState</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Default&quot;</span><span class="kwrd">/&gt;</span>
                            <span class="kwrd">&lt;</span><span class="html">VisualState</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;IsSelected&quot;</span><span class="kwrd">/&gt;</span>
                        <span class="kwrd">&lt;/</span><span class="html">VisualStateGroup</span><span class="kwrd">&gt;</span>
                    <span class="kwrd">&lt;/</span><span class="html">VisualStateManager.VisualStateGroups</span><span class="kwrd">&gt;</span>
                  <span class="kwrd">&lt;</span><span class="html">conv:CustomAdorner</span> <span class="attr">DataContext</span><span class="kwrd">=&quot;{Binding .}&quot;</span><span class="kwrd">/&gt;</span>
                    <span class="kwrd">&lt;</span><span class="html">Border</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;ButtonBorder&quot;</span>
                                        <span class="attr">Margin</span><span class="kwrd">=&quot;-1&quot;</span>
                                        <span class="attr">BorderThickness</span><span class="kwrd">=&quot;4&quot;</span>
                                        <span class="attr">BorderBrush</span><span class="kwrd">=&quot;#AAfffc08&quot;</span>
                                        <span class="attr">Opacity</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span>
                    <span class="kwrd">&lt;</span><span class="html">Border</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;FocusedItemBorder&quot;</span>
                             <span class="attr">Visibility</span><span class="kwrd">=&quot;{Binding IsItemSelected,
                  RelativeSource={RelativeSource TemplatedParent},
                             Converter={StaticResource convBool}}&quot;</span>
                                        <span class="attr">Margin</span><span class="kwrd">=&quot;-1&quot;</span>
                                        <span class="attr">BorderThickness</span><span class="kwrd">=&quot;4&quot;</span>
                                        <span class="attr">BorderBrush</span><span class="kwrd">=&quot;Purple&quot;</span>
                                    <span class="attr">Opacity</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span>
                <span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">ControlTemplate</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Now we have some meat to work with here.&#160; Let’s take a closer look at what is going on.&#160; First you will notice that we added a couple of <strong>VisualStateGroups</strong>.&#160; For this example we are going to leave the IsSelected blank due to that bug I discussed earlier.&#160; In the MouseOver state we are setting our ButtonBorder <strong>Border</strong> objects <strong>Opacity</strong> to 1.</p>
<p>So how do we show the FocusedItemBorder?&#160; The PivotViewerItemAdorner class (whose style we are currently setting) has a <strong>IsItemSelected</strong> property.&#160; By binding the <strong>Visibility</strong> of our <strong>Border</strong> to it, we can toggle based off of that value.&#160; In order to convert the IsItemSelected property from a bool to a <strong>Visibility</strong>, I had to create a <strong>ValueConverter </strong>that looks like this.</p>
<p><em>*Note: This is a handy little <strong>ValueConverter</strong> and you should keep this type of converter handy for your projects.</em></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> BoolToVisibility : IValueConverter
{

    <span class="kwrd">public</span> <span class="kwrd">object</span> Convert(<span class="kwrd">object</span> <span class="kwrd">value</span>,
        Type targetType, <span class="kwrd">object</span> parameter,
        System.Globalization.CultureInfo culture)
    {
        <span class="kwrd">if</span>(<span class="kwrd">value</span> <span class="kwrd">is</span> <span class="kwrd">bool</span>)
        {
            <span class="kwrd">if</span>((<span class="kwrd">bool</span>)<span class="kwrd">value</span>)
            {
                <span class="kwrd">return</span> Visibility.Visible;
            }
        }

        <span class="kwrd">return</span> Visibility.Collapsed;
    }

    <span class="kwrd">public</span> <span class="kwrd">object</span> ConvertBack(<span class="kwrd">object</span> <span class="kwrd">value</span>,
        Type targetType, <span class="kwrd">object</span> parameter,
        System.Globalization.CultureInfo culture)
    {
        <span class="kwrd">throw</span> <span class="kwrd">new</span> NotImplementedException();
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Don’t forget to add the ValueConverter to our XAML so we can reference it in our adorner.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">conv:BoolToVisibility</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;convBool&quot;</span><span class="kwrd">/&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you rerun your application, you should now have two different borders that show on your trading cards.&#160; A yellow border on the mouse over and a purple one when you select the item.&#160; If you were wanting nothing more to get the default borders to work correctly, you are now done.&#160; Hopefully you want to stick around and see how to take this a bit further though. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/wlEmoticon-smile.png" /></p>
<h3></h3>
<h3>Adding Custom XAML</h3>
<p>The above example is a great starting point, but what if we want to add a bit more interactivity in our adorners?&#160; Turns out, it is rather easy (with a few minor catches) to do this.&#160; We are going to wrap the rest of our adorner in a <strong>UserControl</strong>, CustomAdorner.xaml.&#160;&#160; Our UI is going to consist of a single button for the demo’s sake.&#160; Just to separate it from the default item adorner, we will center this button on the bottom of the card.&#160; Here is what our new UserControl looks like:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;LayoutRoot&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;Transparent&quot;</span>  <span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;spContainer&quot;</span> <span class="attr">Orientation</span><span class="kwrd">=&quot;Horizontal&quot;</span>
       <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Bottom&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">=&quot;Time for Change&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;200&quot;</span>
               <span class="attr">Height</span><span class="kwrd">=&quot;50&quot;</span> <span class="attr">Click</span><span class="kwrd">=&quot;Button_Click&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>The <strong>Button</strong> has a <strong>Click</strong> event handler.&#160; Jumping to our code behind, we will show a simple <strong>MessageBox</strong> to prove we are getting what we expect.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> Button_Click(<span class="kwrd">object</span> sender, RoutedEventArgs e)
{
    <span class="kwrd">if</span>(DataContext <span class="kwrd">is</span> DemoItem)
    {
        MessageBox.Show(<span class="str">&quot;DemoItem : &quot;</span>
              + (DataContext <span class="kwrd">as</span> DemoItem).ShortName);
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>With our <strong>UserControl</strong> completed, let’s add it to our item adorner.&#160; </p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">Background</span><span class="kwrd">=&quot;Transparent&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">VisualStateManager.VisualStateGroups</span><span class="kwrd">&gt;</span>
...
    <span class="kwrd">&lt;/</span><span class="html">VisualStateManager.VisualStateGroups</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">conv:CustomAdorner</span> <span class="attr">DataContext</span><span class="kwrd">=&quot;{Binding .}&quot;</span>
        <span class="attr">Visibility</span><span class="kwrd">=&quot;{Binding IsItemSelected,
        RelativeSource={RelativeSource TemplatedParent},
        Converter={StaticResource convBool}}&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Border</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;ButtonBorder&quot;</span>
                <span class="attr">Margin</span><span class="kwrd">=&quot;-1&quot;</span>
                <span class="attr">BorderThickness</span><span class="kwrd">=&quot;4&quot;</span>
                <span class="attr">BorderBrush</span><span class="kwrd">=&quot;#AAfffc08&quot;</span>
                <span class="attr">Opacity</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Border</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;FocusedItemBorder&quot;</span>
            <span class="attr">Visibility</span><span class="kwrd">=&quot;{Binding IsItemSelected,
            RelativeSource={RelativeSource TemplatedParent},
            Converter={StaticResource convBool}}&quot;</span>
                <span class="attr">Margin</span><span class="kwrd">=&quot;-1&quot;</span>
                <span class="attr">BorderThickness</span><span class="kwrd">=&quot;4&quot;</span>
                <span class="attr">BorderBrush</span><span class="kwrd">=&quot;Purple&quot;</span>
            <span class="attr">Opacity</span><span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you rerun the project, you will see that our button is now shown on the trading cards whenever you mouse over a trading card.&#160; If you click the button, you will get a <strong>MessageBox</strong> with the name of the DemoItem displayed.&#160; Instant success right?&#160; Well, sort of.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb.png" width="307" height="206" /></a></p>
<p>You might notice that this isn’t exactly what we are looking for.&#160; If you zoom into an item, the button is positioned nice and neat in the bottom center of card.&#160; However, when zoomed in it looks something like above.&#160; </p>
<p>Why is this happening?&#160; It is important to remember that the trading cards are XAML that have been rendered to an image.&#160; When you define a ItemTemplate, it is always important to design for the largest size that you want to display.&#160; This will insure that your cards always look clean.</p>
<p>This same philosophy is carried over to the item adorners.&#160; The <strong>Grid</strong> in our <strong>UserControl</strong> is adjusting to the current display width and height of the trading card.&#160; However, we defined our <strong>Button</strong> to a static width and height.&#160; Therefore, as you zoom out, the <strong>Button</strong> begins to take up too much space.&#160; The opposite is true if you design it too small.&#160; Zooming into the object will make the <strong>Button</strong> look out of place by being too small.</p>
<p>So how do we address this?&#160; Your first thought might be to change the size of the <strong>Button</strong> as the <strong>Grid</strong> changes its size.&#160; While this will work, what happens when you have more than one element?&#160; What if the item isn’t on the bottom, but is some set offset from the top?&#160; Scaling can quickly become an issue.&#160; </p>
<p>Fortunately, Silverlight has already provided an answer for us. Silverlight 5 contains a control called the <strong>ViewBox</strong>, which use to be a part of the Toolkit.&#160; The <strong>ViewBox</strong> will automatically scale the UI within it to the appropriate size while maintaining accurate spacing, etc. This means that we can scale our <strong>Grid</strong> and everything within it will scale accordingly.</p>
<p>In order to implement our <strong>ViewBox</strong> scenario, we first must decide a base size for our adorner.&#160; This is the size that all of the child elements will be designed to.&#160; For our example, let’s choose 500&#215;500.&#160; We are going to wrap our <strong>StackPanel</strong> inside a new Grid that is set to the 500&#215;500.&#160; That <strong>Grid</strong> will then be wrapped in a <strong>ViewBox</strong>.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;LayoutRoot&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;Transparent&quot;</span> <span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Viewbox</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Container&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;Transparent&quot;</span>
              <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span>
              <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Center&quot;</span>
              <span class="attr">Height</span><span class="kwrd">=&quot;500&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;500&quot;</span>
              <span class="attr">RenderTransformOrigin</span><span class="kwrd">=&quot;0.5,0.5&quot;</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;spContainer&quot;</span>
                        <span class="attr">Orientation</span><span class="kwrd">=&quot;Horizontal&quot;</span>
                        <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span>
                        <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Bottom&quot;</span><span class="kwrd">&gt;</span>
                    <span class="kwrd">&lt;</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">=&quot;Time for Change&quot;</span>
                            <span class="attr">Width</span><span class="kwrd">=&quot;200&quot;</span>
                            <span class="attr">Height</span><span class="kwrd">=&quot;50&quot;</span> <span class="attr">Click</span><span class="kwrd">=&quot;Button_Click&quot;</span>
                            <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span>
                       <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Center&quot;</span><span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Viewbox</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you rerun your application, you will now see that the button scales according to the size of the trading card.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image1.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb1.png" width="265" height="178" /></a></p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/02/image2.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/02/image_thumb2.png" width="256" height="259" /></a></p>
<p>If you wanted the button to only show up when the item is selected, then we can borrow the <strong>Visibility</strong> binding for our selected <strong>Border</strong>.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">conv:CustomAdorner</span> <span class="attr">DataContext</span><span class="kwrd">=&quot;{Binding .}&quot;</span>
                    <span class="attr">Visibility</span><span class="kwrd">=&quot;{Binding IsItemSelected,
    RelativeSource={RelativeSource TemplatedParent},
    Converter={StaticResource convBool}}&quot;</span><span class="kwrd">/&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>And there you have it.&#160; The sky is now the limit on what you can do.&#160; Well, that is until you run into a wall somewhere that I haven’t found.&#160; Regardless, this does open up a great deal of possibilities on what you can add to your trading cards.</p>
<p>You can download the source to this post here : <a href="http://tonyc.me/zSZ9is" target="_blank">PVB05_CustomAdorner.zip</a></p>
<p>As I said at the beginning of this post, this wraps up our basics series.&#160; What’s next?&#160; Well I have a stack of random posts that need to be written to address various topics.&#160; I thought I would then come back and maybe do a series on trading card designs. Until then…</p>
<p>Happy Pivoting…</p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/bXEHEEDvYlY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/02/pivotviewer-basics-custom-item-adorners/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[PivotViewer Basics]]></series:name>
	<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/02/pivotviewer-basics-custom-item-adorners/</feedburner:origLink></item>
		<item>
		<title>PivotViewer Basics : Basic Item Adorners</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/ZkjZXuTe8Gw/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/01/pivotviewer-basics-basic-item-adorners/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 22:25:43 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[PivotViewer]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[item adorners]]></category>
		<category><![CDATA[pivotviewer]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=343</guid>
		<description><![CDATA[After a break to review some of my favorite Silverlight 5 features in the 12 Days of Silverlight series, it’s time to get back to some PivotViewer action.&#160; This is the 4th post in the PivotViewer Basics series focused on some of the basics of the Silverlight 5 PivotViewer.&#160; In this post we will look [...]]]></description>
			<content:encoded><![CDATA[<p>After a break to review some of my favorite Silverlight 5 features in the <a href="http://tonychampion.net/blog/index.php/series/12-days-of-silverlight/" target="_blank">12 Days of Silverlight</a> series, it’s time to get back to some PivotViewer action.&#160; This is the 4th post in the <a href="http://tonychampion.net/blog/index.php/series/pivotviewer-basics/" target="_blank">PivotViewer Basics</a> series focused on some of the basics of the Silverlight 5 PivotViewer.&#160; In this post we will look at item adorners, what they are and how to use them.</p>
<p><span id="more-343"></span>
<p>In the original PivotViewer, there was a concept of custom actions.&#160; Defining custom actions allowed you to add a button on top of the selected trading card.&#160; In fact, you could add several items to the card.&#160; This gave you the ability to provide limited interactivity with the trading card to the user.&#160; The new Silverlight does away with custom actions and replaces them with item adorners. (<em>note: if you implemented custom actions in the previous version, this is another breaking code change</em>)</p>
<p>Simply put, an item adorner is XAML that is placed over a trading card.&#160; If you define an item adorner it is displayed over a trading card when either a mouse over event happens or the item is selected.&#160; This opens a wide range of possibilities for your trading cards.&#160; Now you can add additional information or interactive controls without the need to leave the PivotViewer.&#160; PivotViewer comes with a default adorner, <strong>PivotViewerDefaultItemAdorner</strong> (yep, gotta love those short names).&#160; This adorner mimics the functionality of the custom actions in the previous version.&#160; In this post we will take a look at this new control.</p>
<h3>Implementing the Default Item Adorner</h3>
<p>In order to get us up and running quicker, we are going to start with the project created in the 1st post of the series, <a href="http://tonychampion.net/blog/index.php/2011/11/pv-basics-client-side-collections/" target="_blank">Client-Side Collections</a>.&#160; You can download the code here: <a href="http://tonyc.me/tUL3PR" target="_blank">PVB01_ClientSideCreation.zip</a></p>
<p>Adding the default item adorner is not the most trivial thing in the world, however it’s not overly complicated.&#160; PivotViewer exposes&#160; an <strong>ItemAdornerStyle</strong> property where you can set a style to define your item adorner.&#160; Let’s look at what this style will look like using the <strong>PivotViewerDefaultItemAdorner</strong>.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;basicAdorner&quot;</span>
          <span class="attr">TargetType</span><span class="kwrd">=&quot;pivot:PivotViewerItemAdorner&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;Template&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">ControlTemplate</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">pivot:PivotViewerDefaultItemAdorner</span>
                    <span class="attr">IsItemSelected</span><span class="kwrd">=&quot;{Binding IsItemSelected,
                RelativeSource={RelativeSource TemplatedParent}}&quot;</span>
              <span class="attr">CommandsRequested</span><span class="kwrd">=&quot;basicAdorner_CommandsRequested&quot;</span><span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">ControlTemplate</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>This code creates a style of a <strong>PivotViewerItemAdorner</strong>.&#160; In the template of that control, we are adding a <strong>PivotViewerDefaultItemAdorner</strong>.&#160; The IsItemSelected property binds that property to the base <strong>PivotViewerItemAdorner</strong>.&#160; This let’s us know when the item is simply a mouse-over event or the item has been selected.&#160; The <strong>CommandsRequested</strong> property allows us to create custom commands and display/interact with them on the current trading card.</p>
<p>Here is an example of what the <strong>CommandsRequested</strong> event handler will look like.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> basicAdorner_CommandsRequested(<span class="kwrd">object</span> sender,
    PivotViewerCommandsRequestedEventArgs e)
{
     e.Commands.Add(<span class="kwrd">new</span> AddCommand());
}</pre>
<p>The <strong>PivotViewerCommandRequestedEventArgs</strong> has 3 important properties.&#160; The first, as shown above, is a collection of <strong>IPivotViewerUICommand</strong> objects that defines what commands (aka buttons) to add to the control.&#160; Next is an <strong>Item</strong> property that gives you access to the data object being referred to.&#160; Finally, an <strong>IsItemSelected</strong> property tells us if the object has been selected or not.&#160; We will look at that more in a little while.</p>
<p>The <strong>IPivotViewerUICommand</strong> interface allows you to define what it being displayed to the user and what do to if the user selects it.&#160; Here is what a base implementation of the interface will look like.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Class1 : IPivotViewerUICommand
{

    <span class="kwrd">public</span> <span class="kwrd">string</span> DisplayName
    {
        get { <span class="kwrd">throw</span> <span class="kwrd">new</span> NotImplementedException(); }
    }

    <span class="kwrd">public</span> Uri Icon
    {
        get { <span class="kwrd">throw</span> <span class="kwrd">new</span> NotImplementedException(); }
    }

    <span class="kwrd">public</span> <span class="kwrd">object</span> ToolTip
    {
        get { <span class="kwrd">throw</span> <span class="kwrd">new</span> NotImplementedException(); }
    }

    <span class="kwrd">public</span> <span class="kwrd">bool</span> CanExecute(<span class="kwrd">object</span> parameter)
    {
        <span class="kwrd">throw</span> <span class="kwrd">new</span> NotImplementedException();
    }

    <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler CanExecuteChanged;

    <span class="kwrd">public</span> <span class="kwrd">void</span> Execute(<span class="kwrd">object</span> parameter)
    {
        <span class="kwrd">throw</span> <span class="kwrd">new</span> NotImplementedException();
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>As you can see there isn’t a whole lot going on here.&#160; The <strong>DisplayName</strong>, <strong>ToolTip</strong>, and <strong>Icon</strong> properties are used for the display.&#160; If <strong>CanExecute</strong> returns true, then the <strong>Execute</strong> method is called when the user selects it.&#160; If you go back to our event handler above, you will see that I added an <strong>AddCommand</strong> to the item.&#160; The <strong>AddCommand</strong> class will display a <strong>MessageBox</strong> if the user selects the command.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> AddCommand : IPivotViewerUICommand
{

    <span class="kwrd">public</span> <span class="kwrd">string</span> DisplayName
    {
        get { <span class="kwrd">return</span> <span class="str">&quot;Add Item&quot;</span>; }
    }

    <span class="kwrd">public</span> Uri Icon
    {
        get { <span class="kwrd">return</span> <span class="kwrd">null</span>; }
    }

    <span class="kwrd">public</span> <span class="kwrd">object</span> ToolTip
    {
        get { <span class="kwrd">return</span> <span class="str">&quot;Add Item to cart.&quot;</span>; }
    }

    <span class="kwrd">public</span> <span class="kwrd">bool</span> CanExecute(<span class="kwrd">object</span> parameter)
    {
        <span class="kwrd">return</span> <span class="kwrd">true</span>;
    }

    <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler CanExecuteChanged;

    <span class="kwrd">public</span> <span class="kwrd">void</span> Execute(<span class="kwrd">object</span> parameter)
    {
        var itm = parameter <span class="kwrd">as</span> DemoItem;
        MessageBox.Show( itm.ShortName + <span class="str">&quot; was added&quot;</span>);
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>The only thing left to do is to let our PivotViewer know of the new <strong>ItemAdornerStyle</strong> that we wish to use.&#160; You can set this in code of XAML.&#160; Here we will simply set it in our XAML.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">pivot:PivotViewer</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;pViewer&quot;</span>
    <span class="attr">ItemAdornerStyle</span><span class="kwrd">=&quot;{StaticResource basicAdorner}&quot;</span><span class="kwrd">&gt;</span>
...
<span class="kwrd">&lt;/</span><span class="html">pivot:PivotViewer</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you run the project, you will now see a new command on each trading card when you select it.&#160; Clicking the Add Item button will show a <strong>MessageBox</strong> letting you know that your item has been added to our mythical shopping cart, bug list, or what ever we decide to build. </p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image7.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb7.png" width="203" height="198" /></a></p>
<p>You may also notice that the command will show up whether the item is selected or if you simply mouse over it.&#160; This gets us back to the <strong>IsItemSelected</strong> property of the <strong>PivotViewerCommandRequestedEventArgs</strong>. We can take advantage of this property in our event handler and only add the <strong>AddCommand</strong> if the item is actually selected.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> basicAdorner_CommandsRequested(<span class="kwrd">object</span> sender,
    PivotViewerCommandsRequestedEventArgs e)
{
    <span class="kwrd">if</span> (e.IsItemSelected)
    {
        e.Commands.Add(<span class="kwrd">new</span> AddCommand());
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>If you re-run your application, you will notice that we are no longer showing the command on the mouse over.</p>
<h3>Creating an Interactive Adorner</h3>
<p>The above example shows you how to use the <strong>PivotViewerDefaultItemAdorner</strong> to mimic the custom actions of the first release.&#160; However, this isn’t the first release, so let’s advance things just a bit to get a better feel for how this can work.</p>
<p>For this example, we are going to create a new command.&#160; This new <strong>ColorCommand</strong> will allow us to change the color of the current object.&#160; Like the <strong>AddCommand</strong>, this command is rather straight forward.&#160; However, in the <strong>Execute</strong> method, we will assign the item’s color to the <strong>CommandColor</strong> property defined in the command.&#160; It wasn’t addressed in the example above, but the <strong>parameter</strong> argument that is passed into the <strong>Execute</strong> method is the data object that we are currently interacting with.&#160; Here is what the new ColorCommand looks like.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> ColorCommand : IPivotViewerUICommand
{

    <span class="kwrd">public</span> <span class="kwrd">string</span> CommandColor { get; set; }

    <span class="kwrd">public</span> <span class="kwrd">string</span> DisplayName
    {
        get { <span class="kwrd">return</span> CommandColor; }
    }

    <span class="kwrd">public</span> Uri Icon
    {
        get { <span class="kwrd">return</span> <span class="kwrd">null</span>; }
    }

    <span class="kwrd">public</span> <span class="kwrd">object</span> ToolTip
    {
        get { <span class="kwrd">return</span> <span class="str">&quot;Change color to &quot;</span> + CommandColor; }
    }

    <span class="kwrd">public</span> <span class="kwrd">bool</span> CanExecute(<span class="kwrd">object</span> parameter)
    {
        <span class="kwrd">return</span> <span class="kwrd">true</span>;
    }

    <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler CanExecuteChanged;

    <span class="kwrd">public</span> <span class="kwrd">void</span> Execute(<span class="kwrd">object</span> parameter)
    {
        var itm = parameter <span class="kwrd">as</span> DemoItem;

        itm.Color = CommandColor;
    }
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>Now we need to modify our event handler to add the new command.&#160; We are going to add several command in this example.&#160; The commands we add will be based on the current item’s color.&#160; For example, if the current item is red, then we will add a blue, green, and purple command.&#160; By adding logic into the command creation, we are able to provide a better experience to the user.&#160; For instance, what good does a red button have on a red object?</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> basicAdorner_CommandsRequested(<span class="kwrd">object</span> sender,
    PivotViewerCommandsRequestedEventArgs e)
{

    <span class="kwrd">if</span> (e.IsItemSelected)
    {
        var itm = e.Item <span class="kwrd">as</span> DemoItem;

        <span class="kwrd">if</span>(itm.Color != <span class="str">&quot;Red&quot;</span>)
            e.Commands.Add(<span class="kwrd">new</span> ColorCommand()
                               {
                                   CommandColor = <span class="str">&quot;Red&quot;</span>
                               });
        <span class="kwrd">if</span> (itm.Color != <span class="str">&quot;Blue&quot;</span>)
            e.Commands.Add(<span class="kwrd">new</span> ColorCommand()
                               {
                                   CommandColor = <span class="str">&quot;Blue&quot;</span>
                               });
        <span class="kwrd">if</span> (itm.Color != <span class="str">&quot;Green&quot;</span>)
            e.Commands.Add(<span class="kwrd">new</span> ColorCommand()
                               {
                                   CommandColor = <span class="str">&quot;Green&quot;</span>
                               });
        <span class="kwrd">if</span> (itm.Color != <span class="str">&quot;Purple&quot;</span>)
            e.Commands.Add(<span class="kwrd">new</span> ColorCommand()
                               {
                                   CommandColor = <span class="str">&quot;Purple&quot;</span>
                               });
    }
}</pre>
<p>Running our application now, you will notice that any selected item will have 3 commands.&#160; Selecting the command will update the object and dynamically change the color of the trading card.&#160; Hopefully you can see how this could be very beneficial to you in more advanced situations.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image8.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb8.png" width="244" height="243" /></a></p>
<p>In the next post in this series, we are going to look at creating our own item adorners.&#160; I have received a lot of questions on this subject and thought we would explore it some.&#160; You can download the source code for this project here: <a href="http://tonyc.me/xanELe" target="_blank">PVB04_BasicItemAdorners.zip</a></p>
<p>Until then… Happy Pivoting…</p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/ZkjZXuTe8Gw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/01/pivotviewer-basics-basic-item-adorners/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<series:name><![CDATA[PivotViewer Basics]]></series:name>
	<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/01/pivotviewer-basics-basic-item-adorners/</feedburner:origLink></item>
		<item>
		<title>The Art of Speaking: Scott Hanselman</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/JU6uro-WmV4/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/01/the-art-of-speaking-scott-hanselman/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 16:04:00 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Review]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=336</guid>
		<description><![CDATA[After giving my latest talk last night on the Windows 8 XAML story, I thought I would do a little review of the Scott Hanselman’s TekPub video on The Art of Speaking.&#160; Why?&#160; Truthfully, so that I would have a baseline to come back and review further down the road and I thought a few [...]]]></description>
			<content:encoded><![CDATA[<p>After giving my latest talk last night on the Windows 8 XAML story, I thought I would do a little review of the <a href="http://www.hanselman.com/" target="_blank">Scott Hanselman’s</a> TekPub video on <a href="http://tekpub.com/hanselman" target="_blank">The Art of Speaking</a>.&#160; Why?&#160; Truthfully, so that I would have a baseline to come back and review further down the road and I thought a few people might be interested as well.</p>
<p><span id="more-336"></span><br />
<h3>Setting the Stage</h3>
<p>Before I get into the review itself, let me set the stage a bit first.&#160; I have been giving technical presentations for the last two years.&#160; I don’t really get the opportunity to present as often as I would like, but I give about a dozen presentations a year.&#160; I have had the opportunity to speak at some great conferences, like VS Live, and am looking forward to future opportunities.&#160; Not being a naturally gifted speaker, I still remember my first presentation and what a train wreck it was (it was bad…).</p>
<p>However things have gotten better over the last two years and my presentations continue to improve. I have learned a ton of things over the this time, mostly what not to do, and have received a lot of tips from some very accomplished speakers.&#160; When Scott released the new TekPub video I decided to give a look.&#160; I watched it a few weeks ago and tried to put some of the things I learned into practice last night.&#160; So how did it go?&#160; Well…</p>
<p>I don’t really want to give out too much of the video, but I started off with a bang.&#160; Scott talks about his need to make sure he knows the exact setup of the room, hardware, connectivity, etc.&#160; That point got beat into my head last night with a sledge hammer.</p>
<p>I had given a presentation at this user group a few months back and the projector had a HDMI port.&#160; So I thought nothing off it last night and showed up with my fancy new ultrabook to present my Windows 8 talk on.&#160; I even had a backup machine in case I needed it.&#160; However, it was the Build tablet and guess what, only HDMI.&#160; So imagine how happy I was when a room change put us in a room with no HDMI port.&#160;&#160; After running through several attempts to get a work around, we were finally successful.&#160; Now you geeks out there will probably like this.&#160; We had to create an Ad-Hoc network on another laptop (one with a VGA port) and remote desktop into my box.&#160; It killed my one demo that needed internet access, but it got me up and running.&#160; Boys and girls, anyone care to guess what the lesson we learned here was?</p>
<p>After getting off to a very shaky start, the presentation went well enough.&#160; Ok, no one fell asleep so I figure that has to be a win, right?&#160; On the way home I was reviewing the talk and decided it would be a good idea to write this review.</p>
<h3>Finally, the Video Review…</h3>
<p>Hopefully that gives you a better idea of where I am coming from on this review.&#160; I started off as most technical presenters do and am still working my way to becoming a better speaker.&#160; So that brought me to Scott’s video.&#160; </p>
<p>To sum it up, the video itself is excellent and has probably been the most I have learned about giving presentations in a single shot.&#160; In the video <a href="http://blog.wekeroad.com/" target="_blank">Rob Conery</a> presents Scott with a topic and asks him to prepare and give a 15 minute presentation on it.&#160; That is where the value of this video comes in.&#160; Scott has written several posts over the years on tips to becoming a better speaker and there are several other great resources out there as well.&#160; However, being able to watch an accomplish speaker prep for a talk has a ton of value that you can not get from a list of tips.&#160; It gives you a chance to see how he dissects the topic, preps the demos, and how it all comes together in the final presentation.&#160; Of course the process is scaled back so that it will all fit in a reasonable length video, but you still are able to get a sense of the his process.</p>
<p>So I put some of the things I learned in the video to the test.&#160; First off, preparing for my talk was much easier and I felt much more comfortable with what I had going into my presentation (that is before the HDMI fiasco).&#160; As for the talk itself, I honestly didn’t see a lot of changes though.&#160; Which, at first, was a bit disappointing.&#160; However, when I was reviewing the talk on my way home I started making several connections.&#160; Instead of simply thinking that the talk could have gone better, I began to map specific things that I did or did not do to some of the things I saw in the video.&#160; It gave me a better understanding of what needed to be changed and an example of how I could change it.&#160; To me, that is a win.&#160; It is always easier to improve something when you have an idea of what to improve and how to improve it.</p>
<p>Would I recommend this video? Without a doubt I would.&#160; I believe you can purchase the video by itself for $18.&#160; I went for the annual subscription to TekPub instead.&#160; I honestly think Scott’s video alone would be worth the price of the annual subscription but now I get access to all of TekPub’s other great material as well.&#160; </p>
<p>Scott has some more information about the video and links to his other posts on speaking at <a href="http://speakinghacks.com/" target="_blank">SpeakingHacks.com</a>.&#160; Scott and Rob also have a podcast that is quite interesting called <a href="http://thisdeveloperslife.com/" target="_blank">This Developer’s Life</a>.&#160; Of course they both have very active twitter accounts (@shanselman and @robconery).</p>
<p>For any of the speakers out there, especially the ones just starting or thinking about starting, I wish you all the best.&#160; While speaking is something that I forced myself to start doing, I have really began to enjoy it and hope others do as well.</p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/JU6uro-WmV4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/01/the-art-of-speaking-scott-hanselman/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/01/the-art-of-speaking-scott-hanselman/</feedburner:origLink></item>
		<item>
		<title>12th Day of Silverlight: PivotViewer</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/hleub6ay49I/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/01/12th-day-of-silverlight-pivotviewer/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 15:25:01 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[PivotViewer]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[pivotviewer]]></category>
		<category><![CDATA[silverlight 5]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=333</guid>
		<description><![CDATA[This has been the longest series that I have done and I’ve really had a lot of fun doing it.&#160; If you have missed any of them, you can catch the whole series here: 12 Days of Silverlight.&#160; It’s really nice to see the level of interest in Silverlight 5.&#160; Make sure to drop me [...]]]></description>
			<content:encoded><![CDATA[<p>This has been the longest series that I have done and I’ve really had a lot of fun doing it.&#160; If you have missed any of them, you can catch the whole series here: 12 Days of Silverlight.&#160; It’s really nice to see the level of interest in Silverlight 5.&#160; Make sure to drop me a note if you have anything specific you would like to see more about.&#160; I’m always looking for more topics to write about.&#160; So, for the grand finale…</p>
<p>On the twelfth day of Silverlight the team delivered to me… PivotViewer.</p>
<p><span id="more-333"></span>
<p>Anyone who knows me, knows I have a special interest in the PivotViewer.&#160; Simply poking around this blog should show you that.&#160; I’ve given talks across the country on the subject, I’ve blogged about it, and I’ve even tried to write a book on the subject (although I couldn’t find a publisher to pick it up).&#160; Why the interest?&#160; Because I think it is an amazing example of data visualization.&#160; </p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image4.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb4.png" width="545" height="293" /></a></p>
<h3>History of PivotViewer</h3>
<p>PivotViewer got it’s start in the Live Labs team.&#160; It original appeared as a WPF application called Pivot.&#160; Although no longer supported, you can still download the original application on <a href="http://research.microsoft.com/en-us/downloads/dd4a479f-92d6-496f-867d-666c87fbaada/default.aspx" target="_blank">Microsoft’s Research page</a>.</p>
<p>The first version of PivotViewer was release in 2010 and worked with Silverlight 4.&#160; While containing most of the features you have in the latest version, it’s data was largely static in nature.&#160; It utilized a XML format, CXML, and mapped data items to members of a DeepZoom collection (which was also written by the Live Labs team).&#160; While useful in certain use cases, it’s limited API and static image nature kept the control from being used in many scenarios.</p>
<p>Even with these limitations, the PivotViewer was well received and in time the team moved to the Silverlight team and PivotViewer became an official Silverlight control.&#160; With a major revamp the new PivotViewer came packed with a lot of new goodies.&#160; While still supporting CXML, you can now create client side collections and generate your visuals dynamically with XAML data templates.&#160; The API has been expanded and you now have a lot more control over appearance and behavior.</p>
<p>While still not perfect, it has come a long way and can now be used in a lot of scenarios that it previously couldn’t.</p>
<h3>Anatomy of PivotViewer</h3>
<p>The first two things you need is data and visualizations (hey, maybe that’s where data visualizations came from &lt;grin&gt;).&#160; The new PivotViewer gives you several ways to accomplish this.&#160; Once you populate PivotViewer with both of these, your screen will load and you will see 3 distinct areas.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image5.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb5.png" width="478" height="316" /></a></p>
<p>The main area is the collection container.&#160; It is the heart of the control.&#160; You are able to zoom in and out, pan and scroll with the mouse, etc.&#160; The collection container has two different views: grid view and histogram view.&#160; The grid view lays out your items in a nice grid based on the selected sorting property.&#160; The histogram view will group the items (based on the sorting property) and show them in more of a bar chart.&#160; This gives the user a powerful visualization of comparing counts based on a selected property.&#160; A nice bonus is if you double click a histogram column, it will drill down into that column to give you a finer resolution of the data within.</p>
<p>Above the collection container you have the control bar.&#160; It contains items such as a zoom bar, the sorting property selector, and the ability to switch between grid and histogram view.</p>
<p>To the left you will find the filter panel.&#160; The nicest thing about the filter panel is that it is generated for you.&#160; Each property you define in your data objects is displayed here.&#160; It automatically generates data ranges, value selections, etc.&#160; Adjusting the filter conditions will instantly adjust the items included in the collection container.&#160; Not bad functionality for free.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image6.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb6.png" width="480" height="407" /></a></p>
<p>If you select an item you will see an additional panel displayed on the right, the detail pane.&#160; This contains the specifics about the selected item.&#160; While having a built in view, the new PivotViewer also allows you to create a custom detail pane and I show you a walk through here : <a href="http://tonychampion.net/blog/index.php/2011/10/sl5-pivotviewer-custom-detailpanestyle/" target="_blank">Creating a Custom DetailPaneStyle</a>.</p>
<p>By far the best addition to PivotViewer in SL5 is the dynamic nature of it.&#160; If you make any changes to the data items within the application, the changes are instantly reflected in the information and visualization of the object within the PivotViewer.&#160; This creates a lot of use cases where PivotViewer would be a great fit.</p>
<h3>Developing with PivotViewer</h3>
<p>So I’m going to take the easy way out here and we are not going to run thru a PivotViewer example in this post.&#160; The reason is I have another series on doing just that.&#160; If you want to get your feet wet with the new PivotViewer take a look at my <a href="http://tonychampion.net/blog/index.php/series/pivotviewer-basics/" target="_blank">PivotViewer Basics series</a>.</p>
<p>I do want to make a quick shout out here.&#160; Chris Arnold has two great products out there that include PivotViewer: <a href="http://www.photopivot.com/" target="_blank">PhotoPivot</a> and <a href="http://www.percollate.com/" target="_blank">Percollate</a>. If you want to see some of the exciting ways you can use PivotViewer in your applications, I highly recommend checking both of those out.</p>
<h3>The End of a Series…</h3>
<p>As I said at the beginning of this post, this has been a great series to write.&#160; I think the Silverlight 5 release goes a long ways in the right direction.&#160; There are a lot of additional features that this series did not touch on and I would encourage you to go explore them.&#160; You can find out all about the new release on <a href="http://silverlight.net" target="_blank">Silverlight.net</a>.</p>
<p>I will wrap up this series by stealing a phrase from a good friend of mine (who will probably exclude this post from his site because of it &lt;grin&gt;).</p>
<p>.. stay in the ‘light ..</p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/hleub6ay49I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/01/12th-day-of-silverlight-pivotviewer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[12 Days of Silverlight]]></series:name>
	<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/01/12th-day-of-silverlight-pivotviewer/</feedburner:origLink></item>
		<item>
		<title>11th Day of Silverlight : 3D</title>
		<link>http://feedproxy.google.com/~r/tonychampion/~3/4XRjV2DDN94/</link>
		<comments>http://tonychampion.net/blog/index.php/2012/01/11th-day-of-silverlight-3d/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 13:28:24 +0000</pubDate>
		<dc:creator>Tony Champion</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Silverlight 5]]></category>
		<category><![CDATA[silverlight 5]]></category>

		<guid isPermaLink="false">http://tonychampion.net/blog/?p=324</guid>
		<description><![CDATA[Rounding up the series, we are going to look at a couple of my favorite features in Silverlight 5.&#160; This one has been a hobby of mine sine my college days (which are a lot further away than I care to admit).&#160; Let’s face it, it’s just cool.&#160; That, and it’s let some people do [...]]]></description>
			<content:encoded><![CDATA[<p>Rounding up the series, we are going to look at a couple of my favorite features in Silverlight 5.&#160; This one has been a hobby of mine sine my college days (which are a lot further away than I care to admit).&#160; Let’s face it, it’s just cool.&#160; That, and it’s let some people do some amazing things.</p>
<p>On the eleventh day of Silverlight the team delivered to me… 3D.</p>
<p><span id="more-324"></span>
<p>Yep, that’s right, we now have a 3D stack in Silverlight.&#160; For any of you Xbox developers out there, it should look fairly familiar.&#160; The 3D stack in Silverlight is based off of the XNA framework.&#160; Call it a XNA lite if you will.&#160; While we are not going to build the next blockbuster game, I do think it will be fun to take a look at what 3D looks like inside of Silverlight.</p>
<h3>Creating a 3D Applications</h3>
<p>If you fire up Visual Studio, you will see two new Silverlight solution types available to you : Silverlight 3D Application and Silverlight 3D Library.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb.png" width="550" height="113" /></a></p>
<p>Our example is going to focus on the 3D Application.&#160; If you create the new solution you will see that it creates 4 projects for you.&#160; Two of them should be familiar to you, a SL project and a Web project.&#160; For our 3D application, we have two additional projects (one for the SL side and one for the web).&#160; These projects are there to hold your resources for your application.&#160; In fact, if you try and add a new item to either project you will notice that you are limited to the following items:</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image1.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb1.png" width="550" height="257" /></a></p>
<p>So now that we have a project created, let’s F5 it and see what we get.&#160; Isn’t that a nice little error?&#160; You probably are looking at a notification that you need to enable GPU acceleration.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/SNAGHTMLd67246.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTMLd67246" border="0" alt="SNAGHTMLd67246" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/SNAGHTMLd67246_thumb.png" width="470" height="192" /></a></p>
<p>Now the fun thing is that when you look at the created web pages, you should see that GPU acceleration is already turned on.&#160; So what’s going on?&#160; Well it turns out that elevated trust is required to run 3D applications.&#160; So turning on elevated trust, whether you are in-browser or out, will get you going.&#160; However, you will still need GPU acceleration so don’t turn that off.&#160; </p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image2.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb2.png" width="362" height="41" /></a></p>
<p>Giving the old F5 another try, we see that we have our first 3D application.&#160; It even comes complete with a spinning cube.</p>
<p><a href="http://tonychampion.net/blog/wp-content/uploads/2012/01/image3.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://tonychampion.net/blog/wp-content/uploads/2012/01/image_thumb3.png" width="428" height="322" /></a></p>
<p>Going down the rabbit hole of developing 3D applications is beyond the scope of this post, but I did want you to at least get something up and running.&#160; Make sure you let me know what cool things you come up with.</p>
<p>Eleven down and one to go.&#160; Anyone care to guess what the last post is going be?&#160; See you soon.</p>
<img src="http://feeds.feedburner.com/~r/tonychampion/~4/4XRjV2DDN94" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://tonychampion.net/blog/index.php/2012/01/11th-day-of-silverlight-3d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[12 Days of Silverlight]]></series:name>
	<feedburner:origLink>http://tonychampion.net/blog/index.php/2012/01/11th-day-of-silverlight-3d/</feedburner:origLink></item>
	</channel>
</rss>

