WPF: Gadget-Style User Experience
With gadgets, designers can build shapes and animations to introduce subtle, metaphorical references about the application’s functionality. Gadgets can be built in such a way that they look like objects ‘floating’ in your workspace. You can make them capable of being dragged around so that the user can position them on their desktop according to their preference.
For the purpose of this post, I have developed some XAML code using Microsoft Expression Blend that mimics the look of a plasma TV screen. Interested people can use my previous posts to host or run live videos using this ‘TV’ widget.
To begin with,
a. First set your windows’ WindowStyle to None. This removes the all the Chrome elements associated with your base window.
b. Now, set AllowsTransparency property to True. This step helps you to give that floating effect that adds to the unique gadget user experience.
c. Next up, set Windows’s background to Transparent. This is the key step to get away from the default rectangular window paradigm. These three steps give you the cool gadget look you are looking for.
d. Ideally, you should provide for a way to close the gadget running on your desktop. With the default window missing, you do not have the standard close window button on a custom gadget. Add a button and enable the closing on gadget using code-behind file.
e. One other thing you need to address is the ability to move the window around so that the user has flexibility in positioning the gadget anywhere on the desktop. For this, a good way to handle this is call window’s DragMove method.
Here is the XAML file for such a TV widget implemented in WPF.
XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="infy_blog_on_widget.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" WindowStyle="None" AllowsTransparency="True" Background="Transparent" MouseLeftButtonDown="Window_MouseLeftButtonDown">
<Grid x:Name="process_panel" RenderTransformOrigin="0.5,0.5" Width="771.007" Height="311">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Grid.RenderTransform>
<Rectangle Fill="#FFA4AFE4" Stroke="{x:Null}" RadiusX="20" RadiusY="20" Margin="82.757,-20.5,278.25,56.5" Width="410" Height="275"/>
<Rectangle Stroke="{x:Null}" RadiusX="20" RadiusY="20" Margin="83.723,-22.326,280.285,58.326" RenderTransformOrigin="0.5,0.5" Width="407" Height="275" d:LayoutOverrides="Margin">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.995" ScaleY="0.98"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000" Offset="1"/>
<GradientStop Color="#FFE7EBF9" Offset="0.004"/>
<GradientStop Color="#FFDFE2E8" Offset="0.004"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Stroke="{x:Null}" RadiusX="20" RadiusY="20" Margin="80.941,-14.554,278.066,55.554" RenderTransformOrigin="0.5,0.5" Width="412" Height="270">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.995" ScaleY="0.995"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFD1D3DC" Offset="1"/>
<GradientStop Color="#FFC3D5F2" Offset="0.375"/>
<GradientStop Color="#3FA4BBF0" Offset="0"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Stroke="{x:Null}" RadiusX="5" RadiusY="5" Margin="102,11.5,299.007,79.5" Fill="#FF000000"/>
<Button HorizontalAlignment="Right" Margin="0,-12.5,299.007,0" VerticalAlignment="Top" Width="28" Height="17" Content="Close" Background="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" FontSize="8" Click="Button_Click"/>
</Grid>
</Window>
And here is the code-behind piece to handle closing and drag-moving.
public partial class Window1 : Window
{
public Window1()
{
this.InitializeComponent();
// Insert code required on object creation below this point.
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
}


