Vector image as reusable XAML fragment

c#, resources, wpf, xaml

Solution

You can add the x:Shared attribute to the Path Resource and use it as a StaticResource. This will work if "MyVectorImage" changes to something else

Update Probably better to use a ContentControl or similar to be able to add Properties, such as Margin etc.

<Window.Resources>
    <Path x:Key="MyVectorImage"
          x:Shared="False"
          Stroke="DarkGoldenRod"
          StrokeThickness="3"
          Data="M 10,20 C 10,25 40,35 40,17 H 28"
          Stretch="Fill"
          Width="100"
          Height="40"/>
</Window.Resources>
<StackPanel>
    <ContentControl Margin="10" Content="{StaticResource MyVectorImage}"/>
    <ContentControl Margin="10" Content="{StaticResource MyVectorImage}"/>
</StackPanel>

Example. You replace "MyVectorImage" with a StackPanel containing two Paths.

<Window.Resources>
    <StackPanel x:Key="MyVectorImage"
                x:Shared="False">
        <Path Stroke="DarkGoldenRod"
              StrokeThickness="3"
              Data="M 10,20 C 10,25 40,35 40,17 H 28"
              Stretch="Fill"
              Width="100"
              Height="40"/>
        <Path Stroke="DarkGoldenRod"
              StrokeThickness="3"
              Data="M 10,20 C 10,25 40,35 40,17 H 28"
              Stretch="Fill"
              Width="100"
              Height="40"/>
    </StackPanel>
</Window.Resources>

Problem

I want to reuse some XAML fragment as image in some WPF application/library. The background of the problem is following: It's easy to reuse a bitmap image in a WPF application. The image can be added as a resource, I can use `<Image Source="packURI"/>` at many places in XAML so the image will be the same. But I'd like to have a possibility to do the same for a vector image. The image itself can be represented as `Path`, but I cannot reuse the same `Path` as a resource, because simply using it at several different places (and possibly from several UI threads) is prohibited (UI element can have only one logical parent). Moreover, the question gets more complicated if I'd like to build the "image" from several `Path`s, use a `Canvas` for it. Or some arbitrary XAML code. I tried using a `Style` for the `Path`, so the image is represented in such a way: ``` <Path Style={StaticResource VectorImage1}/> ``` This seems to be a reusable way, but I am concerned with two problems: - If the implementation of a vector image is changed from `Path` to a (for instance) `Canvas`, I'll need to replace it not only in the style, but everywhere in the source code which uses it. - Definition of a path using a style seems to be too verbose. - I see no way to generalize this approach for using `Canvas` or arbitrary XAML code. - The syntax seems to be quite unnatural. There is other way to have a reusable XAML fragment, through defining a `UserControl`, but defining a separate user control for each vector image seems to be an overkill. Is there a better, nice, right way to define a reusable XAML fragment?

Original source

Related problems