Creating images with XAML
In comments to my previous post Benjamin had asked how did I create an image like this:
I used standard PowerPoint SmartArt graphics – it offers rich possibilities and is easy enough to use.
But it suddenly occurred to me that it should be relatively straightforward to use XAML to create a graphic like this – all in all, this is what XAML is actually for. So here's a quick version of that graphic created in Visual Studio 2010 using XAML:
And here's the XAML for it (if you're using WPF version prior to 4.0 remove UseLayoutRounding and TextOptions.TextFormattingMode attributes):
<Window x:Class="WpfApplication1.MainWindow"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="287" Width="519"
UseLayoutRounding="True"
TextOptions.TextFormattingMode="Display"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="12" />
<Setter Property="FontFamily" Value="Verdana" />
</Style>
<Style x:Key="Shadow" TargetType="FrameworkElement">
<Setter Property="BitmapEffect">
<Setter.Value>
<DropShadowBitmapEffect
Color="DarkGray"
Direction="315"
Opacity="0.5"
Softness="0.2"
ShadowDepth="3"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Byte" TargetType="Border" BasedOn="{StaticResource Shadow}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="DimGray" />
<Setter Property="Padding" Value="12,6" />
<Setter Property="Margin" Value="4, 2, 0, 2" />
<Setter Property="MinWidth" Value="35" />
</Style>
<LinearGradientBrush x:Key="Gradient1" StartPoint="0,0" EndPoint="0,1">
<GradientStopCollection>
<GradientStop Color="Honeydew" Offset="0" />
<GradientStop Color="#D0FFC0" Offset="1" />
</GradientStopCollection>
</LinearGradientBrush>
<Style x:Key="SelectedByte" BasedOn="{StaticResource Byte}" TargetType="Border">
<Setter Property="Background" Value="{StaticResource Gradient1}" />
</Style>
<Style x:Key="Arrow" TargetType="Polygon" BasedOn="{StaticResource Shadow}">
<Setter Property="Fill" Value="{StaticResource Gradient1}" />
</Style>
</Window.Resources>
<Grid>
<Canvas>
<Polygon
Style="{StaticResource Arrow}"
Canvas.Left="251"
Canvas.Top="36.5"
Fill="{StaticResource Gradient1}"
StrokeThickness="1"
Stroke="DarkGreen"
Points="10,0 10,25 5,25 15,40 25,25 20,25 20,0 20,0" />
<Polygon
Canvas.Left="102"
Canvas.Top="111"
Fill="{StaticResource Gradient1}"
Points="0,0 162,0 201,40 0,40" />
<TextBlock
Canvas.Left="282"
Canvas.Top="36">
Replace continues from here,<LineBreak /> no further matches
</TextBlock>
<TextBlock
Canvas.Left="199"
Canvas.Top="197">
Need a second pass to replace this one
</TextBlock>
<StackPanel
Canvas.Left="20"
Canvas.Top="80"
Orientation="Horizontal">
<Border Style="{StaticResource Byte}">
<TextBlock>a</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>b</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\r</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\n</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\r</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\n</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>\r</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>\n</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>c</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>d</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock> </TextBlock>
</Border>
</StackPanel>
<StackPanel
Canvas.Left="20"
Canvas.Top="150"
Orientation="Horizontal"
VerticalAlignment="Top">
<Border Style="{StaticResource Byte}">
<TextBlock>a</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>b</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\r</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\n</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock> </TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\r</TextBlock>
</Border>
<Border Style="{StaticResource SelectedByte}">
<TextBlock>\n</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>\r</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>\n</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>c</TextBlock>
</Border>
<Border Style="{StaticResource Byte}">
<TextBlock>d</TextBlock>
</Border>
</StackPanel>
<Polyline
Canvas.Left="227"
Canvas.Top="186"
Points="0,0 0,5 159,5 159,0"
Stroke="Green"
StrokeThickness="2">
</Polyline>
</Canvas>
</Grid>
</Window>
Comments
Anonymous
April 11, 2010
And you wrote the entire XAML code manually, trying to reproduce the one from PowerPoint? I would have stuck with PowerPoint. :)Anonymous
April 12, 2010
Yup :) Well, the benefit is that next time I will need to create a graphic like this, I will tweak this code and it will take me 2-3 minutes.