矢量图像作为可重复使用的XAML片段

时间:2010-12-08 12:20:35

标签: c# wpf xaml resources

我想在一些WPF应用程序/库中重用一些XAML片段作为图像。

问题的背景如下:

在WPF应用程序中重用位图图像很容易。图像可以作为资源添加,我可以在XAML中的许多地方使用<Image Source="packURI"/>,因此图像将是相同的。

但是我想有可能对矢量图像做同样的事情。图像本身可以表示为Path,但我不能重复使用相同的Path作为资源,因为禁止在几个不同的地方(可能来自多个UI线程)使用它(UI元素可以只有一个逻辑父母。)

此外,如果我想从几个Path构建“图像”,问题会变得更复杂,请使用Canvas。或者一些任意的XAML代码。

我尝试使用Style作为Path,因此图像以这样的方式表示:

<Path Style={StaticResource VectorImage1}/>

这似乎是一种可重复使用的方式,但我关注两个问题:

  1. 如果矢量图像的实现从Path更改为(例如)Canvas,我不仅需要在样式中替换它,而且还需要在源代码中的任何位置替换它使用它。
  2. 使用样式定义路径似乎过于冗长。
  3. 我认为概括这种方法无法使用Canvas或任意XAML代码。
  4. 语法似乎很不自然。
  5. 通过定义UserControl,还有其他方法可以获得可重用的XAML片段,但为每个矢量图像定义单独的用户控件似乎是一种过度杀伤。

    是否有更好,更好,正确的方法来定义可重用的XAML片段?

3 个答案:

答案 0 :(得分:15)

您可以将x:Shared属性添加到Path Resource并将其用作StaticResource。如果“MyVectorImage”更改为其他内容

,这将有效

<强>更新
可能更好地使用ContentControl或类似功能来添加属性,例如Margin等。

<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>

实施例。您将“MyVectorImage”替换为包含两个路径的StackPanel。

<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>

答案 1 :(得分:5)

经过一些研究后,还有一个选项:将DrawingImage用作Source作为图片。习惯的图像源是BitmapSource,但它也可以是“矢量图形”。

以下是an example

<Image>
  <Image.Source>
    <DrawingImage PresentationOptions:Freeze="True">
      <DrawingImage.Drawing>
        <GeometryDrawing>
          <GeometryDrawing.Geometry>
            <GeometryGroup>
              <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
              <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
            </GeometryGroup>
          </GeometryDrawing.Geometry>
          <GeometryDrawing.Brush>
            <LinearGradientBrush>
              <GradientStop Offset="0.0" Color="Blue" />
              <GradientStop Offset="1.0" Color="#CCCCFF" />
            </LinearGradientBrush>
          </GeometryDrawing.Brush>
          <GeometryDrawing.Pen>
            <Pen Thickness="10" Brush="Black" />
          </GeometryDrawing.Pen>
        </GeometryDrawing>
      </DrawingImage.Drawing>
    </DrawingImage>
  </Image.Source>
</Image>

产生如此漂亮的矢量图像:

vector image from the source above

另一种选择可能是使用DrawingBrush,就像在这个SO问题中一样:How to store and retrieve multiple shapes in XAML/WPF?

答案 2 :(得分:3)

您可以将路径存储在资源字典中,并将x:Shared设置为false:

<Path x:Key="CrossPath"
      x:Shared="false"
      ...
      />

这将告诉WPF每次请求时都创建一个新实例。 http://msdn.microsoft.com/en-us/library/aa970778.aspx