views:

3103

answers:

2

Any suggestions how to go about having a XAML vector image as a Window background? There's plenty of code showing this with jpg's but I'd prefer a vector based image.

Having it as a resource would be a bonus too but I'm stumped as to the best approach.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Viewbox x:Key="Background2" Stretch="Fill">
        <Canvas >
            <!-- Ebene 1/<Path> -->
            <Path Fill="#ff000000" Data="F1 M 841.890,595.275 L 0.000,595.275 L 0.000,0.000 L 841.890,0.000 L 841.890,595.275 Z"/>
            <!-- Ebene 1/<Path> -->
            <Path Data="F1 M 265.910,218.277 C 265.910,169.332 223.865,129.655 172.000,129.655 C 120.135,129.655 78.090,169.332 78.090,218.277 C 78.090,267.222 120.135,306.898 172.000,306.898 C 223.865,306.898 265.910,267.222 265.910,218.277 Z">
                <Path.Fill>
                    <RadialGradientBrush MappingMode="Absolute" GradientOrigin="172.733,217.234" Center="172.733,217.234" RadiusX="81.912" RadiusY="81.912">
                        <RadialGradientBrush.GradientStops>
                            <GradientStop Offset="0.00" Color="#ff0d4976"/>
                            <GradientStop Offset="0.41" Color="#ff06243b"/>
                            <GradientStop Offset="1.00" Color="#ff000000"/>
                        </RadialGradientBrush.GradientStops>
                        <RadialGradientBrush.Transform>
                            <MatrixTransform Matrix="1.146,0.000,0.000,1.082,-26.038,-16.750" />
                        </RadialGradientBrush.Transform>
                    </RadialGradientBrush>
                </Path.Fill>
            </Path>
        </Canvas>
    </Viewbox>
</ResourceDictionary>

The Resource code above works fine if you remove the Viewbox. The code for the window is :-

  <Window x:Class="Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window2" Height="700" Width="800">
        <Window.Resources>
            <ResourceDictionary Source="Resources/Dictionary2.xaml" />
        </Window.Resources>
        <Grid>
         <StaticResource ResourceKey="Background2"/>   
        </Grid>
    </Window>
A: 

A lot of tools, including Illustrator, allow you to export XAML images in different formats. Your ideal goal is a ResourceDictionary that contains a Canvas or Grid panel, that contains your vector image. Then you could reference the dictionary in your Window.Resources and simply add the image panel (which is a Canvas or Grid) to your top-level Window panel.

So your image .XAML file needs to look something like this:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Canvas x:Name="MyXamlImage">
        ...
    </Canvas>
</ResourceDictionary>

Then in your Window you should have something like:

<Window x:Class="YourNamespace.YourWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="YourWindow" Height="300" Width="300">
    <Window.Resources>
        <ResourceDictionary Source="MyResourceDictionary.xaml">
    </Window.Resources>
    <Grid>
        <StaticResource ResourceKey="MyXamlImage"/>
        ...
    </Grid>
</Window>
Charlie
Hi Charlie, that kinda works but the Canvas size is fixed and I need it to resize with the window. Previously I had put the canvas in a Viewbox with Stretch="Fill" so it resized, but I'm not sure how to adapt this using your method. Any ideas?
Mitch
You can still wrap the Canvas in a Viewbox. Just make the Viewbox the top element of your ResourceDictionary, and give it a name instead of the Canvas.
Charlie
Tried making the Viewbox the top element but it now doesn't show up at all. Very strange..
Mitch
Post your code.
Charlie
Added some sample code. I have to use a x:Key not a x:Name or I get the error "All objects added to an IDictionary must have a Key attribute or some other type of key associated with them." All works well with Canvas, but when I wrap it with a Viewbox, nothing shows.
Mitch
+1  A: 

Try this

<Window.Resources>
    <Canvas x:Key="Background2">
        <!-- Ebene 1/<Path> -->
        <Path Fill="#ff000000" Data="F1 M 841.890,595.275 L 0.000,595.275 L 0.000,0.000 L 841.890,0.000 L 841.890,595.275 Z"/>
        <!-- Ebene 1/<Path> -->
        <Path Data="F1 M 265.910,218.277 C 265.910,169.332 223.865,129.655 172.000,129.655 C 120.135,129.655 78.090,169.332 78.090,218.277 C 78.090,267.222 120.135,306.898 172.000,306.898 C 223.865,306.898 265.910,267.222 265.910,218.277 Z">
            <Path.Fill>
                <RadialGradientBrush MappingMode="Absolute"
                           GradientOrigin="172.733,217.234"
                           Center="172.733,217.234"
                           RadiusX="81.912" RadiusY="81.912">
                    <RadialGradientBrush.GradientStops>
                        <GradientStop Offset="0.00" Color="#ff0d4976"/>
                        <GradientStop Offset="0.41" Color="#ff06243b"/>
                        <GradientStop Offset="1.00" Color="#ff000000"/>
                    </RadialGradientBrush.GradientStops>
                    <RadialGradientBrush.Transform>
                        <MatrixTransform 
                             Matrix="1.146,0.000,0.000,1.082,-26.038,-16.750" />
                    </RadialGradientBrush.Transform>
                </RadialGradientBrush>
            </Path.Fill>
        </Path>
    </Canvas>
</Window.Resources>

<Grid >
    <Grid.Background>
        <VisualBrush Stretch="Fill" Visual="{StaticResource Background2}" />
    </Grid.Background>
</Grid>

You will just have to make a couple of changes to move the resource to your resource dictionary if absolutely necessary.

Simon Fox
Cheers Simon, I'd almost given up on this one. Your solution worked first time. I'm now considering moving it to a resource dictionary so I can have a selection of backgrounds that are user selectable. Thanks again.
Mitch