How do I create vector images for WPF - wpf

I want to use vector images in my WPF-application (for buttons and menus). How do I do that? Which tools should I use? Can someone show my a complete example?

##Tools to create XAML vector images##
Probably the best application to create XAML vector images is Microsoft Expression Design. It’s a free tool that could be downloaded from http://expressiondesign4.com/
When you have installed Expression Design, launch it and select Edit -> Options -> Clipboards (XAML). Change Clipboard format to XAML WPF Resource Dictionary. Also change Group By to Document (otherwise each layer will be an image).
Edit your image in Expression Design. When you are done, select everything and open the Edit menu and then Copy XAML. Paste this in appropriate XAML-file. You see in the example below how it should look like. One thing to note is that you need to change DrawingImage tag to DrawingBrush.
When you are drawing the image set the document size to the size you want in your WPF-application (like 32x32 pixels). It not necessary but make the work easier. Before copy the image to XAML you probably want to make a transparent rectangle that has the same size as the document (otherwise the margins could be wrong). Or you could add this manually in the drawing group children:
<GeometryDrawing Brush="#00FFFFFF" Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z " />
###If you are using Inkscape###
Inkscape has support to generate XAML-files. However - this is probably not the format you want! WPF has two different ways to handle graphics in XAML – shapes and geometries. You can find more details about this here: http://www.intertech.com/Blog/WPF-Shapes-vs-WPF-Geometries/.
But in short shapes has support for inputs, while geometries is just pure drawing and therefor more lightweight.
Inkscape generate files in shape-format, which is good for some cases but not for images that should be used in buttons and similar. So what you want is to get your images into Expression Design. You could do that by saving your image as a PDF-file, change the file extension to AI and then in Expression Design use File, Import Adobe Illustrator File. Using EPS is another option.
Most things could be imported to Expression Design. But it might be some issues with borders for instance. When you have got what you want to Expression Design it’s probably better to do all the work in there. If needed you could export your images to SVG which could be used in Inkscape, that normally works without any problems.
#Example#
When you have created XAML-code for the image it’s then quite straight forward. Below is an example where a vector image is used on a menu and two button.
If you want to draw a very thin line (1 pixel), you may want to add RenderOptions.EdgeMode="Aliased" and SnapsToDevicePixels="True" to the attributes to the control that is drawing the image.
Another thing to have in mind is what to do when a button is disabled. In the example below the image looks the same no matter if the button is enabled or not (this is true for ordinary bitmaps too). Changing the opacity to 50% is one approach that looks quite OK. Converting it grey scale is harder but there is solutions for this too.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
x:Class="VectorGraphicsDemo.MainWindow"
Title="MainWindow"
Height="350"
Width="616">
<Window.Resources>
<!-- Note: When Expression Designed generated the code it was generated
as DrawingBrush. Remember to change this to DrawingImage. -->
<DrawingImage x:Key="TestImage">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#00FFFFFF"
Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z " />
<GeometryDrawing Brush="#FFFF0000"
Geometry="F1 M 6.25,3.97918L 23.125,3.97918L 23.125,16.1458L 6.25,16.1458L 6.25,3.97918 Z ">
<GeometryDrawing.Pen>
<Pen LineJoin="Round"
Brush="#FF000000" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="#FF00C800"
Geometry="F1 M 21.8542,11.0625C 26.399,11.0625 30.0833,14.7468 30.0833,19.2917C 30.0833,23.8365 26.399,27.5208 21.8542,27.5208C 17.3093,27.5208 13.625,23.8365 13.625,19.2917C 13.625,14.7468 17.3093,11.0625 21.8542,11.0625 Z ">
<GeometryDrawing.Pen>
<Pen LineJoin="Round"
Brush="#FF000000" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="#FFFFFF00"
Geometry="F1 M 16.8731,14.9035L 11.9668,16.2498L 8.58953,12.5761L 8.25831,17.6042L 3.62852,19.7405L 8.33013,21.5017L 8.84603,26.4958L 12.083,22.5562L 17.0316,23.5064L 14.3306,19.3103L 16.8731,14.9035 Z ">
<GeometryDrawing.Pen>
<Pen LineJoin="Round"
Brush="#FF000000" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="TestThinLineImage">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#00FFFFFF"
Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z " />
<GeometryDrawing Geometry="F1 M 2,2L 30,2L 30,30L 2,30L 2,2 Z ">
<GeometryDrawing.Pen>
<Pen LineJoin="Round"
Brush="#FF000000" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="F1 M 7,8L 25,8L 25,24L 7,24L 7,8 Z ">
<GeometryDrawing.Pen>
<Pen LineJoin="Round"
Brush="#FFFF0000" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Window.Resources>
<Grid>
<!-- Menu with image -->
<Menu HorizontalAlignment="Stretch"
VerticalAlignment="Top">
<MenuItem Header="Hello">
<MenuItem Header="World">
<MenuItem.Icon>
<Image Source="{StaticResource TestImage}" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<!-- Small standard image -->
<Button HorizontalAlignment="Left"
Margin="12,66,0,0"
VerticalAlignment="Top"
Width="142"
Height="43">
<StackPanel Orientation="Horizontal">
<Image x:Name="imageSmall"
Source="{StaticResource TestImage}"
Height="32"
Width="32" />
<Label VerticalAlignment="Center"
Content="Small image" />
</StackPanel>
</Button>
<!-- Large standard image -->
<Button HorizontalAlignment="Left"
Margin="12,149,0,0"
VerticalAlignment="Top"
Width="142"
Height="75">
<StackPanel Orientation="Horizontal">
<Image x:Name="imageLarge"
Source="{StaticResource TestImage}"
Height="64"
Width="64">
</Image>
<Label VerticalAlignment="Center"
Content="Large image" />
</StackPanel>
</Button>
<!-- Small image with thin line with antialising enabled - looks bad! -->
<Button HorizontalAlignment="Left"
Margin="180,67,0,0"
VerticalAlignment="Top"
Width="177"
Height="43">
<StackPanel Orientation="Horizontal">
<Image x:Name="imageSmall1"
Source="{StaticResource TestThinLineImage}"
Height="32"
Width="32" />
<Label VerticalAlignment="Center"
Content="Small thin anti alias" />
</StackPanel>
</Button>
<!-- Large image with thin line with antialising enabled - looks bad! -->
<Button HorizontalAlignment="Left"
Margin="180,149,0,0"
VerticalAlignment="Top"
Width="177"
Height="75">
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource TestThinLineImage}"
Height="64"
Width="64">
</Image>
<Label VerticalAlignment="Center"
Content="Large thin anti alias" />
</StackPanel>
</Button>
<!-- Small image with thin line with antialising disabled - looks OK! -->
<Button HorizontalAlignment="Left"
Margin="391,67,0,0"
VerticalAlignment="Top"
Width="177"
Height="43">
<StackPanel Orientation="Horizontal">
<Image SnapsToDevicePixels="True"
RenderOptions.EdgeMode="Aliased"
Source="{StaticResource TestThinLineImage}"
Height="32"
Width="32" />
<Label VerticalAlignment="Center"
Content="Small thin alias" />
</StackPanel>
</Button>
<!-- Large image with thin line with antialising disabled - looks OK! -->
<Button HorizontalAlignment="Left"
SnapsToDevicePixels="True"
RenderOptions.EdgeMode="Aliased"
Margin="391,149,0,0"
VerticalAlignment="Top"
Width="177"
Height="75">
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource TestThinLineImage}"
Height="64"
Width="64" />
<Label VerticalAlignment="Center"
Content="Large thin alias" />
</StackPanel>
</Button>
</Grid>

If you've got VS2013, you should have Blend. If not, you can add it from Add/Remove Programs, by modifying your Studio installation and checking the box.
Once you've got Blend, you can build vector images using the slightly too basic tools it provides; but more useful is its ability to import Adobe Illustrator files. This is still the benchmark vector graphics application to work in. This is great if you have a designer to build the assets, or have the skills to do that yourself.
If you need something between the basics of Blend and the all-singing Illustrator, Expression Design is a decent enough option (as already mentioned by #pek).

Related

How to create and use ResourceDictionary of external XAML images

I would like to use icons from Visual Studio icon set for a WPF app and I would like to do it properly using ResourceDictionaries, but it seems more challenging than I thought.
The example icon is a ViewBox provided in a separate XAML file, it's named home_16x.xaml and the XAML content looks like this:
<Viewbox Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Rectangle Width="16" Height="16">
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M7.8786,-0.000199999999999534L-0.000399999999999956,7.8798 -0.000399999999999956,9.4138 0.9996,10.4138 0.9996,15.9998 15.0006,15.9998 15.0006,10.4138 16.0006,9.4138 16.0006,7.8798 8.1206,-0.000199999999999534z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M13,14L10,14 10,9 6,9 6,14 3,14 3,7.707 8,2.707 13,7.707z" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M0.6462,8.6461L1.3532,9.3531 2.0002,8.7071 2.0002,15.0001 7.0002,15.0001 7.0002,10.0001 9.0002,10.0001 9.0002,15.0001 14.0002,15.0001 14.0002,8.7071 14.6462,9.3531 15.3532,8.6461 8.0002,1.2931z M3.0002,7.7071L8.0002,2.7071 12.9992,7.7071 12.9992,14.0001 10.0002,14.0001 10.0002,9.0001 6.0002,9.0001 6.0002,14.0001 3.0002,14.0001z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Viewbox>
If I use the following on my page then it works, but that's not what I am after. It doesn't seem elegant and I would like to keep the option open for switching ResourceDictionaries (for themes).
<Viewbox Width="400" Height="400">
<Frame Source="\Media\Icons\Home_16x.xaml"/>
</Viewbox>
It also shows the following in design view, which is quite confusing:
I would really like to be able to build a dictionary of the icons, that I could call with something like (or cleaner, if possible):
<Viewbox Width="400" Height="400">
<Frame Content="{StaticResource ResourceKey=Icons.Home}"/>
</Viewbox>
My current Icons ResourceDictionary looks like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Viewbox x:Key="Home">
<Viewbox.Resources>
<ResourceDictionary>
<Frame x:Key="Home" Source="\Media\Icons\Home_16x.xaml"/>
</ResourceDictionary>
</Viewbox.Resources>
</Viewbox>
</ResourceDictionary>
I admit I am quite lost. Any help would be much appreciated.
If you use a visualbrush on say a rectangle as fill, that will stretch to whatever size the rectangle is.
Hence you could have a visualbrush in a resource dictionary:
<DrawingBrush x:Key="HomeBrush">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M7.8786,-0.000199999999999534L-0.000399999999999956,7.8798 -0.000399999999999956,9.4138 0.9996,10.4138 0.9996,15.9998 15.0006,15.9998 15.0006,10.4138 16.0006,9.4138 16.0006,7.8798 8.1206,-0.000199999999999534z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M13,14L10,14 10,9 6,9 6,14 3,14 3,7.707 8,2.707 13,7.707z" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M0.6462,8.6461L1.3532,9.3531 2.0002,8.7071 2.0002,15.0001 7.0002,15.0001 7.0002,10.0001 9.0002,10.0001 9.0002,15.0001 14.0002,15.0001 14.0002,8.7071 14.6462,9.3531 15.3532,8.6461 8.0002,1.2931z M3.0002,7.7071L8.0002,2.7071 12.9992,7.7071 12.9992,14.0001 10.0002,14.0001 10.0002,9.0001 6.0002,9.0001 6.0002,14.0001 3.0002,14.0001z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
And use that:
<Rectangle Fill="{StaticResource HomeBrush}" Width="16" Height="16"/>
Or you could let your rectangle fill whatever cell of a grid it's in and omit width and height.
You don't need a viewbox to scale vectors, they can stretch.
You can also use a visualbrush within a path. The path can define one shape with a geometry ( which could be from a resource ) and within that your drawingbrush could put another geometry drawing with a different colour.
An example geometry out a resource file I have:
<Geometry x:Key="BeeIcon">
M15.551045,25.144995L16.748029,25.144995 ....
</Geometry>
I removed a big chunk of the geometry there.
That BeeIcon can then be re-used in different drawinggroups which is useful if you want to construct icons with several parts.
Brushes and colours for them can also be from a resource dictionary so you can switch them out for different themes or branding.

DrawingImage icon gets automatically trimmed when stretch=uniform

We use vector icons exported from Expression Design in our application, but I just noticed that all empty space in the icons gets trimmed away when they are displayed inside a stretched Image. Since the whole point of having vector icons is to allow them to stretch and scale nicely, this seems very strange.
Here is an example. Both the red and the blue star are designed in a 32 pixels wide document, but the blue star is much smaller. Setting the stretch property to Uniform suddenly makes the two icons the same size.
Is it possible to solve this and keep the whitespace around the icons? I guess a possible workaround would be to add a transparent background rectangle that covers the whole icon area, but this seems like a bad solution to me.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="GeneralTest.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<DrawingImage x:Key="small_blue_star">
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="Blue" Geometry="F1 M 20.4989,22C 20.4634,22.0177 16.2771,19.0022 16.2416,19.0022C 16.2061,19.0022 12.0021,22.0177 11.9844,22C 11.9489,21.9823 13.4921,17.0332 13.4744,16.9977C 13.4744,16.9623 9.4655,14.0354 9.48323,13.9999C 9.48323,13.9644 14.45,14.0177 14.4855,13.9999C 14.5032,13.9822 16.2061,8.99765 16.2416,8.99765C 16.2771,8.99765 17.9623,13.9822 17.98,13.9999C 18.0155,14.0177 22.9823,13.9644 23,13.9999C 23,14.0354 18.9911,16.9623 18.9911,16.9977C 18.9734,17.0332 20.5166,21.9823 20.4989,22 Z "/>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="big_red_star">
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="Red" Geometry="F1 M 26.0781,32C 25.9941,32.0436 16.0823,24.6277 15.9983,24.6277C 15.9143,24.6277 5.96055,32.0436 5.91855,32C 5.83455,31.9564 9.48848,19.7856 9.44648,19.6983C 9.44648,19.6111 -0.0453207,12.4133 -0.00332647,12.326C -0.00332647,12.2388 11.7564,12.3697 11.8404,12.326C 11.8824,12.2824 15.9143,0.0243702 15.9983,0.0243702C 16.0823,0.0243702 20.0723,12.2824 20.1142,12.326C 20.1982,12.3697 31.958,12.2388 32,12.326C 32,12.4133 22.5082,19.6111 22.5082,19.6983C 22.4662,19.7856 26.1201,31.9564 26.0781,32 Z "/>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Window.Resources>
<StackPanel x:Name="LayoutRoot">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Stretch=None" Width="100"/>
<Image Source="{StaticResource big_red_star}" Width="32" Stretch="None"/>
<Image Source="{StaticResource small_blue_star}" Width="32" Stretch="None"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Stretch=Uniform" Width="100"/>
<Image Source="{StaticResource big_red_star}" Width="32" Stretch="Uniform" />
<Image Source="{StaticResource small_blue_star}" Width="32" Stretch="Uniform"/>
</StackPanel>
</StackPanel>
</Window>

Problems drawing an "x" in the center of a circle using XAML

I am trying to create a red circle with a black x through it using XAML.
My problem is that they aren't aligned correctly.
What is the right way to do this?
This is what I've got so far:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image>
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Pen>
<Pen Brush="Transparent" Thickness="0"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<EllipseGeometry Center="8,8" RadiusX="8" RadiusY="8"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="2.5"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathFigure StartPoint="4,4">
<LineSegment Point="12,12"/>
</PathFigure>
<PathFigure StartPoint="4,12">
<LineSegment Point="12,4"/>
</PathFigure>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Grid>
Simply putting an ellipse in the same grid with a black X the X isn't quite centered on the ellipse because the coordinates of each line you draw are really coordinates within the space allotted for it.
I think they needed to be in some sort of geometry or drawing aggregate to give them the same coordinate system. The geometry group and path are aggregators but both require their contents to have the same fill and stroke and the stroke and fill is different for the red circle (no stroke) and the black X (no fill).
The only aggregator that gives common coordinate systems and allows different fills & strokes for its members that I could find was the DrawingGroup.
The string shortcuts that work for creating a Path via its Data property don't appear to work for creating a PathGeometry so all had to be filled in by hand.
OK, so three hundred ways to skin a cat. Without fully understanding your use case I just came up with the fastest way to draw what you requested.
<Grid HorizontalAlignment="Left"
Height="80"
Margin="80,80,0,0"
VerticalAlignment="Top"
Width="80">
<Ellipse Fill="Red"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<Path Data="M40,53 L48,69 62,69 49,46 61,24 48,24 C48,24 40,39 40,39 40,39 32,24 32,24 L18,24 30,46 17,69 31,69 z"
Fill="Black"
Margin="15"
Stretch="Fill"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Grid>
This is probably outside what exactly you're looking for, but hopefully it at least gives you another way to think about it.
I had the same issue when trying to center text within an ellipse. The problem with using something like a TextBlock is that the kerning and escapement of each character is slightly different and so while the TextBlock element itself might be technically centered within the ellipse, this does not mean that the character will be centered in the ellipse. The character always appears to be too low and to the right of center in most situations.
I have had some success by wrapping the TextBlock in a ViewBox. While I am not fully versed in the technical implementation of the ViewBox, the ViewBox appears to wrap the visual rendering of the content which allows me to center that rendering more easily than trying to center to layout elements together.
I also seem to have better luck using an outer element that is of odd width/height rather than even width and height.
<Grid Width="19"
Height="19">
<Ellipse Fill="#FFB1413F"
StrokeThickness="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<Viewbox HorizontalAlignment="Center"
VerticalAlignment="Stretch">
<TextBlock Text="X"
Margin="1"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Viewbox>
</Grid>

WPF: Solid color ImageSource

In my app I display images I get from external DLLs, by binding the Source of an Image control to an ImageSource.
This works well, but sometimes I don't get any data from my DLL and I'd like to just show a black image. In that case, how do I create an ImageSource which contains just a solid color?
An alternative method is to give a background color, and not show the image.
// XAML
<Grid Background="Black">
<Image x:Name="imgDisplay"/>
</Grid>
// C#
imgDisplay.Source = null;
// -- OR --
imgDisplay.Visibility = Visibility.Collapsed;
for example you have image somewhere in template, which binds to some property Photo. In case of failure you can return null value.
<Image Source="{Binding Path=Photo, IsAsync=True, TargetNullValue={StaticResource EmptyImageDrawing}}"/>
And somewhere in resources you need
<DrawingImage
x:Key="EmptyImageDrawing">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Brush>
<VisualBrush
AlignmentX="Center"
AlignmentY="Center"
Stretch="None">
<VisualBrush.Visual>
<TextBlock
Text="Failed to load photo"
FontFamily="Calibri"
FontSize="70"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
TextAlignment="Center"
TextWrapping="Wrap"/>
</VisualBrush.Visual>
</VisualBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Geometry>
<RectangleGeometry
Rect="0,0,1920,1080" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>

Preventing deformation in XAML Grid's background when resizing

I am writing a brush in XAML that I can use to paint the background of a Grid to create a banner. It looks like this:
I want the brush to "stretch" with the Grid when the Window resizes, but I do not want the center angles to deform.
I only need to be able to draw the shapes in the background of a Grid. How can I avoid the deformation?
The code I've written looks like this:
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="60" Width="300">
<Window.Resources>
<DrawingBrush x:Key="GridBackground">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Geometry="M0,1 0,0 0.4,0 0.45,0.5 0.4,1Z" Brush="#FF6A00" />
<GeometryDrawing Geometry="M0.6,1 0.55,0.5 0.6,0 1,0 1,1Z" Brush="#FF0000" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Window.Resources>
<Grid Background="{StaticResource GridBackground}">
<TextBlock Foreground="White" VerticalAlignment="Center">Some text</TextBlock>
</Grid>
</Window>
I would make it two brushes, one anchored to the right, and one anchored to the left. Something like this:
<Grid>
<GeometryXXX Geometry="M0,1 0,0 0.4,0 0.45,0.5 0.4,1Z" Width="300" HorizontalAlignment="Left" Brush="#FF6A00">
<GeometryXXX Geometry="M0,1 0,0 0.4,0 0.45,0.5 0.4,1Z" Width="300" HorizontalAlignment="Right" Brush="#FF0000">
<TextBlock Foreground="White" VerticalAlignment="Center">Some text</TextBlock>
</Grid>
I don't have my compiler open, and I don't remember the name of the Geometry drawing object.
The other way of doing it would be to create a valueconverter, and do something like:
...
<GeometryDrawing Geometry="{Binding Width, ValueConverter=LeftAngledThing}" Brush="#FF6A00" />
<GeometryDrawing Geometry="{Binding Width, ValueConverter=LeftAngledThing}" Brush="#FF0000" />
...
You would need to look up the exact syntax for how to do this though, as I don't remember it right now.

Resources