Sunday 16 December 2012

Tracking MouseMove in Silverlight

namespace MouseTracking
{
public partial class MainPage
{
readonly MouseTracker tracker = new MouseTracker();

public MainPage()
{
InitializeComponent();
tracker.StartTracking(this);
}
}
}
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;

namespace MouseTracking
{
public class MouseTracker
{
public MouseTracker()
{
TraceMouse = true;
}

public bool TraceMouse { get; set; }

public void StartTracking(UserControl sender)
{
sender.Loaded += sender_Loaded;
//TODO: Hook into specific FrameworkElements events? MouseOver, select, click, etc
}

void sender_Loaded(object sender, RoutedEventArgs e)
{
var page = (UserControl) sender;
page.MouseLeftButtonDown += page_MouseLeftButtonDown;
page.SizeChanged += page_SizeChanged;
page.MouseMove += page_MouseMove;
page.KeyDown += page_KeyDown;
page.Unloaded += page_Unloaded;

var data = string.Format("resolution={0}x{1}",
HtmlPage.Window.Eval("screen.width"),
HtmlPage.Window.Eval("screen.height"));

Write(DateTime.Now, page.ToString(), "Loaded", data);
}

void page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var data = string.Format("ClickCount={0}", e.ClickCount);

Write(DateTime.Now, sender.ToString(), "page_MouseLeftButtonDown", data);
}

void page_SizeChanged(object sender, SizeChangedEventArgs e)
{
var data = string.Format("screen={0}x{1} page={2}x{3}",
(Application.Current.RootVisual as FrameworkElement).ActualWidth,
(Application.Current.RootVisual as FrameworkElement).ActualHeight,
(sender as FrameworkElement).ActualWidth,
(sender as FrameworkElement).ActualHeight);

Write(DateTime.Now, sender.ToString(), "SizeChanged", data);

}

private void page_KeyDown(object sender, KeyEventArgs e)
{
Write(DateTime.Now, sender.ToString(), "KeyDown", string.Format("key={0}", e.Key));
}

void page_Unloaded(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Removing event handlers");

var page = (UserControl)sender;
page.Loaded -= sender_Loaded;
page.MouseLeftButtonDown -= page_MouseLeftButtonDown;
page.SizeChanged -= page_SizeChanged;
page.MouseMove -= page_MouseMove;
page.KeyDown -= page_KeyDown;
page.Unloaded -= page_Unloaded;
}

void page_MouseMove(object sender, MouseEventArgs e)
{
Write(DateTime.Now, sender.ToString(), "MouseMove", string.Format("coord={0},{1}", e.GetPosition(null).X, e.GetPosition(null).Y));
}

private void Write(DateTime time, string page, string eventName, string data)
{
string ipAddress = Application.Current.Resources["ipAddress"].ToString();

// call service here (ipaddress can be retrieved serverside using HttpContext object)
// for now we'll just output to debug window

if (TraceMouse)
Debug.WriteLine("{0} {1} {2} {3} {4}", ipAddress, time.ToString("MM/dd/yyyy HH:mm:ss.fff"), page, eventName, data);
}
}
}
<body>
<form id="form1" runat="server" style="height:100%">
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/MouseTracking.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="5.0.61118.0" />
<param name="initParams" value="ipAddress=<%= Request.UserHostAddress %>"/>
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</form>
</body>
</html>
private void Application_Startup(object sender, StartupEventArgs e)
{
if (e.InitParams != null)
{
foreach (var item in e.InitParams)
{
this.Resources.Add(item.Key, item.Value);
}
}

this.RootVisual = new MainPage();
}

Source:  https://github.com/stevenh77/MouseTracking

Wednesday 5 December 2012

PivotViewer ItemsLoaded event

Here is an example of the PivotViewer extended to feature an ItemsLoaded event.

This event fires when all the item data templates/trading cards have finished rendering.

Live demo:  http://stevenhollidge.com/blog-source-code/pivotviewerwithitemsloadedevent

using System;
using System.ComponentModel;
using System.Windows.Controls.Pivot;
using System.Windows.Threading;

namespace PivotViewerDemo
{
public class MetroPivotViewer : PivotViewer, INotifyPropertyChanged
{
private readonly UiHelper layoutUpdatedFinished;

private string title;
public string Title
{
get { return title; }
set
{
if (title == value) return;
title = value;
NotifyPropertyChanged("Title");
}
}

private bool isLoading;
public bool IsLoading
{
get { return isLoading; }
set
{
if (isLoading == value) return;
isLoading = value;
NotifyPropertyChanged("IsLoading");
}
}

public MetroPivotViewer()
{
layoutUpdatedFinished = new UiHelper();
IsLoading = true;

this.StateSynchronizationFinished += MetroPivotViewer_StateSynchronizationFinished;
this.LayoutUpdated += MetroPivotViewer_LayoutUpdated;
}

void MetroPivotViewer_LayoutUpdated(object sender, EventArgs e)
{
layoutUpdatedFinished.Reset();
}

void MetroPivotViewer_StateSynchronizationFinished(object sender, EventArgs e)
{
layoutUpdatedFinished.SetTimeout(300, () =>
{
IsLoading = false;
this.View = this.GraphView;
NotifyItemsLoaded();
});
}

public event EventHandler ItemsLoaded;
public void NotifyItemsLoaded()
{
if (ItemsLoaded != null)
ItemsLoaded(this, null);
}

#region INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}

#endregion

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

public class UiHelper
{
private readonly DispatcherTimerContainingAction timer;

public UiHelper()
{
timer = new DispatcherTimerContainingAction();
}

public void SetTimeout(int milliseconds, Action action)
{
timer.Interval = new TimeSpan(0, 0, 0, 0, milliseconds);
timer.Action = action;
timer.Tick += OnTimeout;
timer.Start();
}

public void Reset()
{
timer.Stop();
timer.Start();
}

private void OnTimeout(object sender, EventArgs arg)
{
timer.Stop();
timer.Tick -= OnTimeout;
timer.Action();
}
}

public class DispatcherTimerContainingAction : DispatcherTimer
{
public Action Action { get; set; }
}
}

Source:  https://github.com/stevenh77/PivotViewerWithItemsLoadedEvent

Monday 3 December 2012

Application Library Caching with PRISM

Your main Shell project xap file will reference all your application dependencies with Copy Local = true, which ensures your application has the DLL available.

For each referenced library, if it has been signed and a *.extmap.xml file is found in the same directory as the DLL then a zip file will be created for it in the Web Server ClientBin folder.  If not then the DLL will be be copied directly into the Shell.xap.

All your “Module” project / xap files should reference their dependencies with Copy Local = false.  This will let Visual Studio build each module project xap files but not copy the referenced libraries into the xap.

imageFor example this is the Prism extmap.xml file:

extmap

<?xml version="1.0"?>
<manifest>
<assembly>
<name>Microsoft.Practices.Prism</name>
<version>4.1.0.0</version>
<publickeytoken>31bf3856ad364e35</publickeytoken>
<relpath>Microsoft.Practices.Prism.dll</relpath>
<extension downloadUri="Microsoft.Practices.Prism.zip" />
</assembly>
</manifest>

AppManifest.xaml


This file is contained within each xap file and lets Silverlight know whether dependencies can be found within the xap or externally.


  • The “Deployment.Parts” section contains the libraries with Copy to Local = true.

  • The “Deployment.ExternalParts” section contains libraries with Copy to Local = false.

Note:  When PRISM loads modules it does not automatically download ExternalParts, see here. Here is an example of an AppManifest.xaml file:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="PivotViewerDemo" EntryPointType="PivotViewerDemo.App" RuntimeVersion="5.0.61118.0">
<Deployment.Parts>
<AssemblyPart x:Name="PivotViewerDemo" Source="PivotViewerDemo.dll" />
<AssemblyPart x:Name="System.Xml.Serialization" Source="System.Xml.Serialization.dll" />
<AssemblyPart x:Name="System.Xml.Linq" Source="System.Xml.Linq.dll" />
</Deployment.Parts>
<Deployment.ExternalParts>
<ExtensionPart Source="System.Windows.Controls.zip" />
<ExtensionPart Source="System.Windows.Controls.Pivot.zip" />
</Deployment.ExternalParts>
</Deployment>

Configuring Silverlight application projects (Xap files)


Don’t forget to switch on application library caching for all your Silverlight applications (Shell and module projects).

image

How to cache your own Silverlight libraries


Simply sign the library (Project > Properties > Signing) by creating a new key file which requires a password then manually create an extmap.xml file:


image


Where to find the extmap.xml files


If you don’t have access to the extmap.xml files just create them yourself. 


You’ll need to know the assembly version number, right click on the file in Windows Explorer, select properties then click the Details tab.


assembly version


To find out the public key token use the sn.exe (strong name) application that comes with Visual Studio:


sn


See earlier in this blog post for an example of an *.extmap.dll file.


I want to store copies of each of my references within my code base, where can I find the DLLs


While many people use Nuget nowadays you may still wish to store the DLLs files yourself.  Here is a quick lust of locations so you can find them.


The Silverlight “core” libraries do not have to be included in either xap or zip files and can always be set to Copy Local False and do not need to be stored within your code base.


image


Other Microsoft and third party libraries can be added to a libraries (libs) folder within your solution, don’t forget to include the extmap.xml files.  Once the files are installed the Microsoft SDK files can be found here:


image


PRISM libraries can be downloaded from CodePlex:  http://compositewpf.codeplex.com/


Expression libraries can be downloaded from Blend SDK, Blend Service Pack, Silverlight Tools SP1, VS 2010 SP1.

Wednesday 28 November 2012

Telerik Silverlight GridView click events


// Single click
this.TradesGrid.SelectionChanged += TradesGridSelectionChanged;

// Double click
this.TradesGrid.AddHandler(GridViewCellBase.CellDoubleClickEvent,
new EventHandler<RadRoutedEventArgs>(OnCellDoubleClick), true);

......

void TradesGridSelectionChanged(object sender, SelectionChangeEventArgs e)
{
if (e.AddedItems.Count == 0) return;

var trade = e.AddedItems[0] as Trade;
if (trade == null) return;

var vm = DataContext as ViewModel;
if (vm == null) return;

vm.OpenTradeForDocumenting(trade);
}

private void OnCellDoubleClick(object sender, RadRoutedEventArgs e)
{
var cell = e.Source as GridViewCell;
if (cell == null) return;

var row = cell.ParentRow as GridViewRow;
if (row == null) return;

var trade = row.DataContext as Trade;
if (trade == null) return;

var vm = DataContext as ViewModel;
if (vm == null) return;

vm.OpenTradeForDocumenting(trade);
}

Tuesday 27 November 2012

Sorting PivotViewer Silverlight5

There is a sort property on the PivotViewerProperty but that’s used to sort the filter on the left hand side of the page (see sector is sorted by quantity, then A-Z on sector).

To sort within a group you need to implement an IComparable interface on an aggregate property.  Here’s what I mean:

image

You’ll see this data is “sorted” by Sector, which actually groups but within each group the data is sorted by coupon (the big number in the middle).  Here’s how I did it:

private string sector;
public string Sector
{
get { return sector; }
set { sector = value; NotifyProperty("Sector"); }
}

private ValueSortByCoupon sectorSort;
public ValueSortByCoupon SectorSort
{
get { return sectorSort ?? (sectorSort = new ValueSortByCoupon(Sector, CouponToday)); }
}

....

public class ValueSortByCoupon : IComparable
{
private string Value { get; set; }
private decimal Coupon { get; set; }

public ValueSortByCoupon(string sector, decimal coupon)
{
this.Value = sector;
this.Coupon = coupon;
}

public int CompareTo(object rhs)
{
var other = (ValueSortByCoupon)rhs;
var result = this.Value == other.Value
? other.Coupon.CompareTo(this.Coupon)
: this.Value.CompareTo(other.Value);
return result;
}

public override string ToString()
{
return Value;
}
}
<pivot:PivotViewer>
<pivot:PivotViewer.PivotProperties>
<pivot:PivotViewerStringProperty Id="SectorSort"
DisplayName="Sector"
Options="CanFilter,CanSearchText"
Binding="{Binding SectorSort, Mode=OneWay}" />
</pivot:PivotViewer.PivotProperties>
</pivot:PivotViewer>

Source:  http://github.com/stevenh77/pivotviewerdemo

Friday 23 November 2012

Silverlight ToggleButton Metro style

You can download the source code here:   https://github.com/stevenh77/ToggleSL

For additional styles check out the library:   http://toggleswitch.codeplex.com/

toggletoggle2

<UserControl x:Class="ToggleSL.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ToggleSwitch="clr-namespace:ToggleSwitch;assembly=ToggleSwitch"
xmlns:Borders="clr-namespace:ToggleSwitch.Borders;assembly=ToggleSwitch"
xmlns:Utils="clr-namespace:ToggleSwitch.Utils;assembly=ToggleSwitch"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<UserControl.Resources>
<ControlTemplate x:Key="EngravedContentTemplate" TargetType="ContentControl">
<TextBlock
Cursor="{TemplateBinding Cursor}"
Text="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
FontStyle="{TemplateBinding FontStyle}" />
</ControlTemplate>

<ControlTemplate x:Key="ThumbWithDoubleArrowTemplate" TargetType="Thumb">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="0.05" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="0.25" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="0.05" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Checked"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Borders:OuterGlowBorder OuterGlowSize="0" OuterGlowOpacity="0" BorderThickness="0" OuterGlowColor="Black" Background="Transparent" CornerRadius="0" ShadowCornerRadius="0" IsTabStop="False" >
<Grid>
<Borders:ClippingBorder x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" IsTabStop="False" Background="{TemplateBinding Background}">
<StackPanel Orientation="Horizontal" Height="6" HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Data="M0,0 L0,6 L-5,3" Fill="{TemplateBinding Foreground}" Stretch="Fill" StrokeThickness="0" Margin="0,0,2,0"/>
<Path Data="M0,0 L0,6 L5,3" Fill="{TemplateBinding Foreground}" Stretch="Fill" StrokeThickness="0" Margin="2,0,0,0"/>
</StackPanel>
</Borders:ClippingBorder>
<Borders:ClippingBorder x:Name="BackgroundAnimation" Background="Black" Opacity="0" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Black" CornerRadius="0" IsTabStop="False"/>
<Rectangle x:Name="DisabledVisualElement" Fill="White" IsHitTestVisible="false" Opacity="0" RadiusY="0" RadiusX="0"/>
<Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" RadiusY="0" RadiusX="0" StrokeThickness="1"/>
</Grid>
</Borders:OuterGlowBorder>
</Grid>
</ControlTemplate>

<Style x:Key="CarbonToggleSwitchStyle" TargetType="ToggleSwitch:HorizontalToggleSwitch">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Width" Value="88"/>
<Setter Property="Height" Value="28"/>
<Setter Property="BorderBrush" Value="#FFBEBEBE"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="0,4"/>
<Setter Property="UncheckedForeground" Value="#FF5C5C5C"/>
<Setter Property="CheckedForeground" Value="White"/>
<Setter Property="ThumbSize" Value="42"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="ContentTemplate" Value="{StaticResource EngravedContentTemplate}"/>
<Setter Property="ThumbTemplate" Value="{StaticResource ThumbWithDoubleArrowTemplate}"/>
<Setter Property="CheckedBackground">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF81B5FB" Offset="1"/>
<GradientStop Color="#FF5D9FF2" Offset="0.50"/>
<GradientStop Color="#FF569BEF" Offset="0.50"/>
<GradientStop Color="#FF3772B9"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="UncheckedBackground">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFBBBBBB" Offset="0"/>
<GradientStop Color="#FFE1E2E2" Offset="0.5"/>
<GradientStop Color="#FFDDDDDD" Offset="0.5"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="ThumbBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFD8D7D8"/>
<GradientStop Color="#FFFDFCFD" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleSwitch:HorizontalToggleSwitch">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="DisabledOverlay">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.10" To="Unchecked"/>
<VisualTransition GeneratedDuration="0:0:0.10" To="Checked"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Checked"/>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="DraggingChecked"/>
<VisualState x:Name="DraggingUnchecked"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Borders:ClippingBorder x:Name="SwitchRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" CornerRadius="0" IsTabStop="False">
<Canvas MinWidth="{TemplateBinding ThumbSize}" MinHeight="{TemplateBinding FontSize}">
<Utils:ActualSizePropertyProxy x:Name="ActualSizeProxy" Element="{Binding Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Visibility="Collapsed"/>
<Grid x:Name="SwitchTrack" Cursor="Hand" Height="{Binding ActualHeightValue, ElementName=ActualSizeProxy, Mode=OneWay}" Margin="0,-1,0,0">
<StackPanel Orientation="Horizontal">
<Border Background="{TemplateBinding CheckedBackground}" Margin="-1,0,0,0" Padding="1,0,0,0">
<ContentControl x:Name="SwitchChecked" Content="{TemplateBinding CheckedContent}" Foreground="{TemplateBinding CheckedForeground}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="Center" IsTabStop="False" Margin="{TemplateBinding Padding}" Padding="0,0,22,0" Template="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="Center"/>
</Border>
<Border Background="{TemplateBinding UncheckedBackground}" Margin="-1,0,0,0">
<ContentControl x:Name="SwitchUnchecked" Content="{TemplateBinding UncheckedContent}" Foreground="{TemplateBinding UncheckedForeground}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="Center" IsTabStop="False" Margin="{TemplateBinding Padding}" Template="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="Center"/>
</Border>
</StackPanel>
</Grid>
<Borders:InnerGlowBorder BorderThickness="0" Background="#00000000" CornerRadius="0" Height="{Binding ActualHeightValue, ElementName=ActualSizeProxy, Mode=OneWay}" IsHitTestVisible="False" IsTabStop="False" InnerGlowOpacity="0" InnerGlowColor="Black" InnerGlowSize="0" Margin="-1,-1,0,0" Width="{Binding ActualWidthValue, ElementName=ActualSizeProxy, Mode=OneWay}"/>
<Thumb x:Name="SwitchThumb" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding ThumbBrush}" Cursor="Hand" Foreground="#FF359CE6" HorizontalAlignment="Left" Height="{Binding ActualHeightValue, ElementName=ActualSizeProxy, Mode=OneWay}" IsTabStop="False" Margin="0,-1,0,0" Template="{TemplateBinding ThumbTemplate}" Width="{TemplateBinding ThumbSize}"/>
</Canvas>
</Borders:ClippingBorder>
<Border x:Name="DisabledOverlay" Background="#AAEEEEEE" CornerRadius="0" Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">

<ToggleSwitch:HorizontalToggleSwitch
Margin="20"
VerticalAlignment="Top"
BorderBrush="#FFB4B0B0"
Width="78"
UncheckedBackground="#FFD6D4D4"
UncheckedForeground="#FFFFFFFF"
ThumbSize="22"
Style="{StaticResource CarbonToggleSwitchStyle}" IsChecked="True" HorizontalAlignment="Left">
<ToggleSwitch:HorizontalToggleSwitch.CheckedBackground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#ff3074aa"/>
<GradientStop Color="#FFB9D6ED" Offset="1"/>
</LinearGradientBrush>
</ToggleSwitch:HorizontalToggleSwitch.CheckedBackground>
<ToggleSwitch:HorizontalToggleSwitch.ThumbBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFD6D4D4"/>
<GradientStop Color="#FFD6D4D4" Offset="1"/>
<GradientStop Color="#FFD6D4D4" Offset="0.02"/>
</LinearGradientBrush>
</ToggleSwitch:HorizontalToggleSwitch.ThumbBrush>
</ToggleSwitch:HorizontalToggleSwitch>

</Grid>
</UserControl>

Wednesday 21 November 2012

Delay in Silverlight

public class ActionDispatcherTimer : System.Windows.Threading.DispatcherTimer
{
public Action Action { get; set; }
}

public static class UIHelper
{
public static void DelayStart(int milliseconds, Action action)
{
var timer = new ActionDispatcherTimer
{
Interval = new TimeSpan(0, 0, 0, 0, milliseconds),
Action = action
};
timer.Tick += onTick;
timer.Start();
}

private static void onTick(object sender, EventArgs arg)
{
var t = sender as ActionDispatcherTimer;
t.Stop();
t.Action();
t.Tick -= onTick;
}
}

//usage: after 5 seconds execute ths lambda
UIHelper.DelayStart(5000, () => status = "Completed");


Taken from:  http://blog.bodurov.com/How-to-Create-setTimeout-Function-in-Silverlight/

Sunday 18 November 2012

Creating Excel file in C#

Before you start you’ll want to install Open XML SDK 2.0 for Microsoft Office:

http://www.microsoft.com/en-us/download/details.aspx?id=5124

Now create a new C# console app and add a reference to the DocumentFormat.OpenXml assembly.

image
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace CreatingExcelFile
{
class Program
{
static void Main(string[] args)
{
// Make a copy of the template file.
File.Copy(@"blank.xlsx", @"generated.xlsx", true);

// Open the copied template workbook.
using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(@"generated.xlsx", true))
{
// Access the main Workbook part, which contains all references.
WorkbookPart workbookPart = myWorkbook.WorkbookPart;

// Get the first worksheet.
WorksheetPart worksheetPart = workbookPart.WorksheetParts.ElementAt(2);

// The SheetData object will contain all the data.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();

// output our headers
var data = new[] { "ID", "TRADE", "PRICE"};
var row = CreateNewRow(1, data);

sheetData.AppendChild(row);

// Begining Row pointer
int rowIndex = 2;

// For each item in the database, add a Row to SheetData.
foreach (var trade in GetTradeData())
{
// the data written in each row
data = new [] {trade.Id.ToString(), trade.Asset, trade.Price.ToString()};

// create the Excel row with our data
row = CreateNewRow(rowIndex, data );

// Append Row to SheetData
sheetData.AppendChild(row);

// increase row pointer
rowIndex++;
}

// save
worksheetPart.Worksheet.Save();
}
}

private static Row CreateNewRow(int rowIndex, params string[] data)
{
// New Row
Row row = new Row { RowIndex = (UInt32)rowIndex };

for (int i = 0; i < data.Length; i++)
{
// A = 65 for the first column, B = 66, C = 67...
string column = ((char) (65 + i)).ToString();

// New Cell
Cell cell = new Cell
{
DataType = CellValues.InlineString,
CellReference = column + rowIndex
};

// Create Text object
Text t = new Text {Text = data[i]};

// Append Text to InlineString object
InlineString inlineString = new InlineString();
inlineString.AppendChild(t);

// Append InlineString to Cell
cell.AppendChild(inlineString);

// Append Cell to Row
row.AppendChild(cell);
}
return row;
}

public static IList<Trade> GetTradeData()
{
var list = new List<Trade>(6)
{
new Trade() {Id = Guid.NewGuid(), Asset = "APPLE", Price = (decimal) 33.89},
new Trade() {Id = Guid.NewGuid(), Asset = "BMW", Price = (decimal) 1.23},
new Trade() {Id = Guid.NewGuid(), Asset = "CAPCOM", Price = (decimal) 87.46},
new Trade() {Id = Guid.NewGuid(), Asset = "FUSE", Price = (decimal) 4.24},
new Trade() {Id = Guid.NewGuid(), Asset = "IBM", Price = (decimal) 103.66},
new Trade() {Id = Guid.NewGuid(), Asset = "MICROSOFT", Price = (decimal) 45.55}
};
return list;
}
}

public class Trade
{
public Guid Id { get; set; }
public string Asset { get; set; }
public decimal Price { get; set; }
}
}

 


image


Source:  https://github.com/stevenh77/CreatingExcelFile


For Silverlight AgOpenXml library has samples for Word and Excel:   http://agopenxml.codeplex.com

Creating a Metro PivotViewer

using System.Windows.Controls;
using System.Windows.Controls.Pivot;

namespace PivotViewerDemo
{
public class MetroPivotViewer : PivotViewer
{
public override void OnApplyTemplate()
{
base.OnApplyTemplate();

// an alternative to changing style is to do magic here...
}
}
}

PivotViewer Custom Filter Pane

Original Filter Pane vs Restyled (ever so slightly)

image  image

Up close you can see the clear all button has been restyled and the drop shadow removed:

image

image

<UserControl x:Class="PivotViewerDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pivot="clr-namespace:System.Windows.Controls.Pivot;assembly=System.Windows.Controls.Pivot"
xmlns:local="clr-namespace:PivotViewerDemo"
mc:Ignorable="d">
<pivot:PivotViewer x:Name="pivotViewer">

<pivot:PivotViewer.PivotProperties>
<pivot:PivotViewerNumericProperty Id="CouponToday"
DisplayName="Coupon Today"
Options="CanFilter"
Binding="{Binding CouponToday, Mode=OneWay}" />
<pivot:PivotViewerNumericProperty Id="Barrier"
Options="CanFilter"
Binding="{Binding Barrier, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Underlying"
Options="CanFilter,CanSearchText"
Binding="{Binding Underlying, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Maturity"
Options="CanFilter"
Binding="{Binding Maturity, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Sector"
Options="CanFilter,CanSearchText"
Binding="{Binding Sector, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Currency"
Options="CanFilter"
Binding="{Binding Currency, Mode=OneWay}" />
</pivot:PivotViewer.PivotProperties>

<pivot:PivotViewer.ItemTemplates>

<pivot:PivotViewerItemTemplate MaxWidth="150">
<Grid Height="150"
Width="150"
Background="{Binding MaturityColour, Mode=OneTime}" />
</pivot:PivotViewerItemTemplate>

<pivot:PivotViewerItemTemplate>
<Border Width="300"
Height="300"
Background="{Binding MaturityColour, Mode=OneTime}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="4*" />
<RowDefinition Height="2.5*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock Text="Maturity"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

<TextBlock Text="{Binding Maturity, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1" />

<TextBlock Text="Barrier"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="2" />

<TextBlock Text="{Binding Barrier, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="2" />

<TextBlock Text="{Binding CouponToday, Mode=OneTime}"
FontSize="100"
FontFamily="Segoe UI Light"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Grid.Row="2"
Grid.ColumnSpan="3" />

<TextBlock Text="{Binding Underlying, Mode=OneTime}"
FontSize="32"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="3"
Grid.ColumnSpan="3"
TextWrapping="Wrap" />

<TextBlock Text="{Binding Sector, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.Row="4"
Grid.ColumnSpan="2"
Margin="10,0,0,5" />

<TextBlock Text="{Binding Currency, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Grid.Row="4"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="0,0,10,5" />

</Grid>
</Border>
</pivot:PivotViewerItemTemplate>
</pivot:PivotViewer.ItemTemplates>

<pivot:PivotViewer.ItemAdornerStyle>
<Style TargetType="pivot:PivotViewerItemAdorner">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="pivot:PivotViewerItemAdorner">
<pivot:PivotViewerDefaultItemAdorner IsTabStop="False" CommandsRequested="GetCommands" IsItemSelected="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsItemSelected}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</pivot:PivotViewer.ItemAdornerStyle>

<pivot:PivotViewer.FilterPaneStyle>
<Style TargetType="pivot:PivotViewerFilterPane">
<Setter Property="Foreground"
Value="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="Background"
Value="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="BorderBrush"
Value="{Binding BorderBrush, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="AccentColor"
Value="{Binding AccentColor, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="Background"
Value="{Binding SecondaryBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="ControlBackground"
Value="{Binding ControlBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="SecondaryForeground"
Value="{Binding SecondaryForeground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="pivot:PivotViewerFilterPane">
<Grid x:Name="FilterPaneRoot"
Background="Transparent"
Width="185"
Margin="5,5,0,5">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>

<Rectangle Fill="{TemplateBinding SecondaryBackground}"
Grid.RowSpan="3"
RadiusX="3"
RadiusY="2"
IsHitTestVisible="False" />
<Rectangle x:Name="m_Background"
Fill="{TemplateBinding SecondaryBackground}"
Stroke="{TemplateBinding BorderBrush}"
Grid.RowSpan="3"
RadiusX="3"
RadiusY="2" />
<Button x:Name="PART_ClearAllButton"
AutomationProperties.Name="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ClearAllButtonText}"
Grid.Row="0"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ClearAllButtonText}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="Center"
HorizontalAlignment="Right"
Height="25"
Margin="2,4,4,4" />
<ContentControl HorizontalContentAlignment="Stretch"
Grid.Row="1"
x:Name="PART_CustomSearchBoxContainer"
Margin="4,0,4,3"
IsTabStop="False">
</ContentControl>

<ScrollViewer x:Name="PART_CategoriesContainer"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Grid.Row="2"
BorderBrush="{x:Null}"
Padding="1"
IsTabStop="False">
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</pivot:PivotViewer.FilterPaneStyle>

<pivot:PivotViewer.DetailPaneStyle>
<Style TargetType="pivot:PivotViewerDetailPane">
<Setter Property="Foreground" Value="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="Background" Value="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="BorderBrush" Value="{Binding BorderBrush, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="AccentColor" Value="{Binding AccentColor, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="Background" Value="{Binding SecondaryBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="ControlBackground" Value="{Binding ControlBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="SecondaryForeground" Value="{Binding SecondaryForeground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="PrimaryItemValueBackgroundColor" Value="{Binding PrimaryItemValueBackgroundColor, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=pivot:PivotViewer}}" />
<Setter Property="SecondaryItemValueBackgroundColor" Value="{Binding SecondaryItemValueBackgroundColor, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=pivot:PivotViewer}}" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="{Binding MaturityColour, Mode=OneTime}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="4*" />
<RowDefinition Height="2.5*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock Text="Maturity"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

<TextBlock Text="{Binding Maturity, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1" />

<TextBlock Text="Barrier"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="2" />

<TextBlock Text="{Binding Barrier, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="2" />

<TextBlock Text="{Binding CouponToday, Mode=OneTime}"
FontSize="100"
FontFamily="Segoe UI Light"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Grid.Row="2"
Grid.ColumnSpan="3" />

<TextBlock Text="{Binding Underlying, Mode=OneTime}"
FontSize="32"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="3"
Grid.ColumnSpan="3"
TextWrapping="Wrap" />

<TextBlock Text="{Binding Sector, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.Row="4"
Grid.ColumnSpan="2"
Margin="10,0,0,5" />

<TextBlock Text="{Binding Currency, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Grid.Row="4"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="0,0,10,5" />

</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</pivot:PivotViewer.DetailPaneStyle>
</pivot:PivotViewer>
</UserControl>

PivotViewer Custom Detail Pane

image

<UserControl x:Class="PivotViewerDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pivot="clr-namespace:System.Windows.Controls.Pivot;assembly=System.Windows.Controls.Pivot"
xmlns:local="clr-namespace:PivotViewerDemo"
mc:Ignorable="d">
<pivot:PivotViewer x:Name="pivotViewer">

<pivot:PivotViewer.PivotProperties>
<pivot:PivotViewerNumericProperty Id="CouponToday"
DisplayName="Coupon Today"
Options="CanFilter"
Binding="{Binding CouponToday, Mode=OneWay}" />
<pivot:PivotViewerNumericProperty Id="Barrier"
Options="CanFilter"
Binding="{Binding Barrier, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Underlying"
Options="CanFilter,CanSearchText"
Binding="{Binding Underlying, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Maturity"
Options="CanFilter"
Binding="{Binding Maturity, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Sector"
Options="CanFilter,CanSearchText"
Binding="{Binding Sector, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Currency"
Options="CanFilter"
Binding="{Binding Currency, Mode=OneWay}" />
</pivot:PivotViewer.PivotProperties>

<pivot:PivotViewer.ItemTemplates>

<pivot:PivotViewerItemTemplate MaxWidth="150">
<Grid Height="150"
Width="150"
Background="{Binding MaturityColour, Mode=OneTime}" />
</pivot:PivotViewerItemTemplate>

<pivot:PivotViewerItemTemplate>
<Border Width="300"
Height="300"
Background="{Binding MaturityColour, Mode=OneTime}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="4*" />
<RowDefinition Height="2.5*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock Text="Maturity"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

<TextBlock Text="{Binding Maturity, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1" />

<TextBlock Text="Barrier"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="2" />

<TextBlock Text="{Binding Barrier, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="2" />

<TextBlock Text="{Binding CouponToday, Mode=OneTime}"
FontSize="100"
FontFamily="Segoe UI Light"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Grid.Row="2"
Grid.ColumnSpan="3" />

<TextBlock Text="{Binding Underlying, Mode=OneTime}"
FontSize="32"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="3"
Grid.ColumnSpan="3"
TextWrapping="Wrap" />

<TextBlock Text="{Binding Sector, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.Row="4"
Grid.ColumnSpan="2"
Margin="10,0,0,5" />

<TextBlock Text="{Binding Currency, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Grid.Row="4"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="0,0,10,5" />

</Grid>
</Border>
</pivot:PivotViewerItemTemplate>
</pivot:PivotViewer.ItemTemplates>

<pivot:PivotViewer.ItemAdornerStyle>
<Style TargetType="pivot:PivotViewerItemAdorner">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="pivot:PivotViewerItemAdorner">
<pivot:PivotViewerDefaultItemAdorner IsTabStop="False" CommandsRequested="GetCommands" IsItemSelected="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsItemSelected}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</pivot:PivotViewer.ItemAdornerStyle>

<pivot:PivotViewer.DetailPaneStyle>
<Style TargetType="pivot:PivotViewerDetailPane">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="{Binding MaturityColour, Mode=OneTime}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="4*" />
<RowDefinition Height="2.5*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock Text="Maturity"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

<TextBlock Text="{Binding Maturity, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1" />

<TextBlock Text="Barrier"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="2" />

<TextBlock Text="{Binding Barrier, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="2" />

<TextBlock Text="{Binding CouponToday, Mode=OneTime}"
FontSize="100"
FontFamily="Segoe UI Light"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Grid.Row="2"
Grid.ColumnSpan="3" />

<TextBlock Text="{Binding Underlying, Mode=OneTime}"
FontSize="32"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="3"
Grid.ColumnSpan="3"
TextWrapping="Wrap" />

<TextBlock Text="{Binding Sector, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.Row="4"
Grid.ColumnSpan="2"
Margin="10,0,0,5" />

<TextBlock Text="{Binding Currency, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Grid.Row="4"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="0,0,10,5" />

</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</pivot:PivotViewer.DetailPaneStyle>
</pivot:PivotViewer>
</UserControl>

Pivot Viewer Simple Custom Adorners

When the user hovers over an item they see “Book price” appear in the top right hand corner.

When they click this area it fires a command, which shows Boom! … along with the price properties:

image

image

<UserControl x:Class="PivotViewerDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pivot="clr-namespace:System.Windows.Controls.Pivot;assembly=System.Windows.Controls.Pivot"
xmlns:local="clr-namespace:PivotViewerDemo"
mc:Ignorable="d">
<Grid>
<pivot:PivotViewer x:Name="pivotViewer">

<pivot:PivotViewer.PivotProperties>
<pivot:PivotViewerNumericProperty Id="CouponToday"
DisplayName="Coupon Today"
Options="CanFilter"
Binding="{Binding CouponToday, Mode=OneWay}" />
<pivot:PivotViewerNumericProperty Id="Barrier"
Options="CanFilter"
Binding="{Binding Barrier, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Underlying"
Options="CanFilter,CanSearchText"
Binding="{Binding Underlying, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Maturity"
Options="CanFilter"
Binding="{Binding Maturity, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Sector"
Options="CanFilter,CanSearchText"
Binding="{Binding Sector, Mode=OneWay}" />
<pivot:PivotViewerStringProperty Id="Currency"
Options="CanFilter"
Binding="{Binding Currency, Mode=OneWay}" />
</pivot:PivotViewer.PivotProperties>

<pivot:PivotViewer.ItemTemplates>

<pivot:PivotViewerItemTemplate MaxWidth="150">
<Grid Height="150"
Width="150"
Background="{Binding MaturityColour, Mode=OneTime}" />
</pivot:PivotViewerItemTemplate>

<pivot:PivotViewerItemTemplate>
<Border Width="300"
Height="300"
Background="{Binding MaturityColour, Mode=OneTime}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="4*" />
<RowDefinition Height="2.5*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock Text="Maturity"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

<TextBlock Text="{Binding Maturity, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1" />

<TextBlock Text="Barrier"
FontSize="12"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="2" />

<TextBlock Text="{Binding Barrier, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="2" />

<TextBlock Text="{Binding CouponToday, Mode=OneTime}"
FontSize="100"
FontFamily="Segoe UI Light"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Grid.Row="2"
Grid.ColumnSpan="3" />

<TextBlock Text="{Binding Underlying, Mode=OneTime}"
FontSize="32"
FontFamily="Segoe UI"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="3"
Grid.ColumnSpan="3"
TextWrapping="Wrap" />

<TextBlock Text="{Binding Sector, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Grid.Row="4"
Grid.ColumnSpan="2"
Margin="10,0,0,5" />

<TextBlock Text="{Binding Currency, Mode=OneTime}"
FontSize="22"
FontFamily="Segoe UI"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Grid.Row="4"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="0,0,10,5" />

</Grid>
</Border>
</pivot:PivotViewerItemTemplate>
</pivot:PivotViewer.ItemTemplates>

<pivot:PivotViewer.ItemAdornerStyle>
<Style TargetType="pivot:PivotViewerItemAdorner">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="pivot:PivotViewerItemAdorner">
<pivot:PivotViewerDefaultItemAdorner IsTabStop="False"
CommandsRequested="GetCommands"
IsItemSelected="{Binding RelativeSource={RelativeSource
TemplatedParent},
Path=IsItemSelected}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</pivot:PivotViewer.ItemAdornerStyle>

</pivot:PivotViewer>
</Grid>
</UserControl>
using System.Windows.Controls.Pivot;

namespace PivotViewerDemo
{
public partial class MainPage
{
public MainPage()
{
InitializeComponent();

this.pivotViewer.ItemsSource = Factory.GetData();
}

private void GetCommands(object sender, PivotViewerCommandsRequestedEventArgs e)
{
e.Commands.Add(new AdornerCommand(e.Item as Price));
}
}
}
using System;
using System.Windows;
using System.Windows.Controls.Pivot;

namespace PivotViewerDemo
{
public class AdornerCommand : IPivotViewerUICommand
{
private readonly Price price;

public AdornerCommand(Price price)
{
this.price = price;
}

#region IPivotViewerUICommand

public string DisplayName
{
get { return "Book price"; }
}

public Uri Icon
{
get { return null; }
}

public object ToolTip
{
get { return "Click this to book the price"; }
}

#endregion

public bool CanExecute(object parameter)
{
return true;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
MessageBox.Show(string.Format("Boom!{0}{0}{1}", Environment.NewLine, price.ToString()));
}
}
}