Monday 28 May 2012

Silverlight Metro Charms

Here’s a quick example of a Silverlight application with a Charms style menu from Windows 8.

The menu slides in and out as the user moves the mouse over the right hand side of the screen.  When displayed the menu holds ImageButtons that when clicked, display a UIMessage to the user.

Give it a try by moving your mouse over the right hand side of this iframe, over the tall black rectangle:

MainPage.xaml

<UserControl x:Class="MetroCharms.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:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:MetroCharms"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">

<Grid x:Name="LayoutRoot">

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="HideShowMenu">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3" />
</VisualStateGroup.Transitions>
<VisualState x:Name="HideMenu" />
<VisualState x:Name="ShowMenu">
<Storyboard>
<DoubleAnimation d:IsOptimized="True"
Duration="0"
Storyboard.TargetName="menuPanel"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
To="-60" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

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

<local:UIMessage x:Name="Message" />

<StackPanel x:Name="menuPanel"
Grid.Column="1"
Width="68"
Height="340"
Margin="0,0,-60,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Background="Black">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<ei:GoToStateAction StateName="ShowMenu" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<ei:GoToStateAction StateName="HideMenu" />
</i:EventTrigger>
</i:Interaction.Triggers>
<StackPanel.RenderTransform>
<CompositeTransform />
</StackPanel.RenderTransform>

<local:ImageButton x:Name="imageButtonSettings"
Width="48"
Height="48"
Margin="10"
Click="imageButtonSettings_Click"
Image="/MetroCharms;component/images/settings.png"
PressedImage="/MetroCharms;component/images/settings.png"
Template="{StaticResource ImageButtonControlTemplate}" />
<local:ImageButton x:Name="imageButtonSave"
Width="48"
Height="48"
Margin="10"
Click="imageButtonSave_Click"
Image="/MetroCharms;component/images/save.png"
PressedImage="/MetroCharms;component/images/save.png"
Template="{StaticResource ImageButtonControlTemplate}" />
<local:ImageButton x:Name="imageButtonCamera"
Width="48"
Height="48"
Margin="10"
Click="imageButtonCamera_Click"
Image="/MetroCharms;component/images/camera.png"
PressedImage="/MetroCharms;component/images/camera.png"
Template="{StaticResource ImageButtonControlTemplate}" />
<local:ImageButton x:Name="imageButtonFavs"
Width="48"
Height="48"
Margin="10"
Click="imageButtonFavs_Click"
Image="/MetroCharms;component/images/favs.png"
PressedImage="/MetroCharms;component/images/favs.png"
Template="{StaticResource ImageButtonControlTemplate}" />
<local:ImageButton x:Name="imageButtonFlag"
Width="48"
Height="48"
Margin="10"
Click="imageButtonFlag_Click"
Image="/MetroCharms;component/images/flag.png"
PressedImage="/MetroCharms;component/images/flag.png"
Template="{StaticResource ImageButtonControlTemplate}" />
</StackPanel>

</Grid>
</UserControl>

ImageButton.cs

public class ImageButton : Button
{
public ImageButton()
{
DefaultStyleKey = typeof(ImageButton);

MouseEnter += (o, args) => Cursor = Cursors.Hand;
MouseLeave += (o, args) => Cursor = Cursors.None;
}

public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButton), null);

public ImageSource Image
{
get { return (ImageSource)this.GetValue(ImageProperty); }
set { this.SetValue(ImageProperty, value); }
}

public static readonly DependencyProperty PressedImageProperty =
DependencyProperty.Register("PressedImage", typeof(ImageSource), typeof(ImageButton), null);

public ImageSource PressedImage
{
get { return (ImageSource)this.GetValue(PressedImageProperty); }
set { this.SetValue(PressedImageProperty, value); }
}
}

App.xaml

<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MetroCharms"
x:Class="MetroCharms.App">

<Application.Resources>
<ControlTemplate x:Key="ImageButtonControlTemplate" TargetType="local:ImageButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="PressedImage">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="NormalImage">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image x:Name="NormalImage" Source="{TemplateBinding Image}"/>
<Image x:Name="PressedImage" Source="{TemplateBinding PressedImage}" Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</Application.Resources>
</Application>

Source


https://github.com/stevenh77/MetroCharms

No comments:

Post a Comment