共用方式為


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:

image

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.