C# 矢量图像作为可重用的XAML片段
我想在一些WPF应用程序/库中重用一些XAML片段作为图像 问题的背景如下: 在WPF应用程序中重用位图图像很容易。图像可以作为资源添加,我可以在XAML中的许多地方使用C# 矢量图像作为可重用的XAML片段,c#,wpf,xaml,resources,C#,Wpf,Xaml,Resources,我想在一些WPF应用程序/库中重用一些XAML片段作为图像 问题的背景如下: 在WPF应用程序中重用位图图像很容易。图像可以作为资源添加,我可以在XAML中的许多地方使用,这样图像就会相同 但我想对矢量图像也能这样做。图像本身可以表示为路径,但我不能将相同的路径重用为资源,因为禁止在多个不同的位置(可能从多个UI线程)简单地使用它(UI元素只能有一个逻辑父级) 此外,如果我想从多个路径s构建“图像”,那么问题会变得更复杂,请使用画布。或者一些任意的XAML代码 我尝试对路径使用样式,因此图像的表
,这样图像就会相同
但我想对矢量图像也能这样做。图像本身可以表示为路径
,但我不能将相同的路径
重用为资源,因为禁止在多个不同的位置(可能从多个UI线程)简单地使用它(UI元素只能有一个逻辑父级)
此外,如果我想从多个路径
s构建“图像”,那么问题会变得更复杂,请使用画布
。或者一些任意的XAML代码
我尝试对路径使用样式
,因此图像的表示方式如下:
<Path Style={StaticResource VectorImage1}/>
这似乎是一种可重用的方式,但我关心两个问题:
如果向量图像的实现从Path
更改为(例如)Canvas
,那么我不仅需要在样式上替换它,还需要在使用它的源代码中的任何地方替换它
使用样式定义路径似乎过于冗长
我看不出有任何方法可以将这种方法推广到使用Canvas
或任意XAML代码
语法似乎很不自然
还有其他方法可以获得可重用的XAML片段,通过定义一个UserControl
,但是为每个向量图像定义一个单独的用户控件似乎有些过分
有没有更好、更好、正确的方法来定义可重用的XAML片段?您可以将路径存储在资源字典中,并将x:Shared设置为false:
<Path x:Key="CrossPath"
x:Shared="false"
...
/>
这将告诉WPF在每次请求时创建一个新实例。
您可以将x:Shared属性添加到路径资源中,并将其用作静态资源。如果“MyVectorImage”更改为其他内容,这将起作用
更新
最好使用ContentControl或类似工具来添加属性,如边距等
<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>
经过一些研究,还有一个选择:对图像使用as源代码。通常的图像源是一个矢量图形,但也可以是“矢量图形”
这是:
生成如此漂亮的矢量图像:
还有一个选项可能是使用画笔
,就像这个问题:。这对任意WPF片段有效吗?例如,带有子元素的画布
?非常感谢;您的建议基本上与接受的答案相同。感谢您解释shared=false的实际作用,它解决了我的问题。我尝试使用您的建议,但在运行时遇到了一个异常:“命名空间“http://schemas.microsoft.com/winfx/2006/xaml”中的共享属性只能在已编译的资源字典中使用。”我将MyVectorImage
移动到一个单独的XAML资源字典中,但当我将该字典包含到窗口的合并字典中时,我收到了相同的错误消息。@Vlad@I更新了我的示例。如果您尝试StackPanel的示例,我忘记将x:Shared属性移动到StackPanel。我明白了,我的错,我应该试着理解消息的确切内容。x:Shared仅在顶层运行。@Vlad:Yes,我在尝试运行它时遇到了相同的异常。。它在designer中表现得很好,所以我没有费心去尝试运行它:)酷对我来说很有用。现在我可以在单独的资源字典中保存我所有的矢量图形了!我更喜欢这种方法,但我认为答案将受益于一些内联代码示例。通过使用DrawingImage,可以将元素用作DrawingImage的内容属性,将多个矢量图形(和多种颜色)组合成一个内聚图标。它还允许您在UI代码中始终使用图标元素,而不管您是指矢量图像还是位图图像;“Source”属性将引用DrawingImage矢量资源或BitmapSource图像资源。@BTownTKD:没错,我将尝试构造一些示例示例示例链接已断开且无法恢复。(该成员的MSDN内容没有示例。)有人可以在此网站上共享内容吗?@LonelyPixel:我已经更正了链接并内联了示例。
<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>