XAML SVG运行时颜色更改

4

我们有一组存储在资源字典中的SVG。

例如:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DrawingImage x:Key="Bell">
        <DrawingImage.Drawing>
            <DrawingGroup Opacity="1">
                <DrawingGroup.Children>
                    <DrawingGroup Opacity="1">
                        <DrawingGroup.Children>
                            <DrawingGroup Opacity="1">
                                <DrawingGroup.Children>
                                    <GeometryDrawing Brush="#FF000000" Pen="{x:Null}">
                                        <GeometryDrawing.Geometry>
                                            <PathGeometry FillRule="Nonzero" Figures="........." />
                                        </GeometryDrawing.Geometry>
                                    </GeometryDrawing>
                                </DrawingGroup.Children>
                            </DrawingGroup>
                        </DrawingGroup.Children>
                    </DrawingGroup>
                </DrawingGroup.Children>
            </DrawingGroup>
        </DrawingImage.Drawing>
    </DrawingImage>
</ResourceDictionary>

如果您注意到GeometryDrawing Brush设置为#ff000000(黑色)。 我们面临的问题是允许视图在运行时显示此SVG并分配颜色(通过绑定)。
我们的窗口(视图)具有Resource Dictionary,其中包含Window.Resources中的图标。
我们正在寻找以下解决方案:
<Image Source="{StaticResource Bell}" Fill="#FF884422"/>

这似乎是我要走的路线,你有可以分享的示例吗? - user856197
是的,我马上就要开始开会了,但是午饭后我会回来并尽快帮你解决问题。 - Chris W.
Chris,在你的模板中,你放置了什么?是PathGeometry还是只有Path值? - user856197
你可以在那里放任何你喜欢的东西,我忘记我在这里回答了一个类似的问题(https://dev59.com/xGYr5IYBdhLWcg3w7eTb#13293017),所以你可以参考一下,然后你可以为你想要在模板中命中的依赖属性设置setter,只要你使用{TemplateBinding blah},这将允许你做一些像<ContentControl Fill="Red" Stroke="Blue"/>等等的事情。 - Chris W.
我尝试了以下代码(删除了一些XAML),但是{TemplateBinding Background}似乎不起作用。 - user856197
显示剩余6条评论
4个回答

4
请看这个工具:https://github.com/BerndK/SvgToXaml。该工具可以自动将所有svg转换为一个xaml,颜色可以一次性设置所有图像或仅针对单个图像进行设置。示例代码包括在内,可用于在运行时更改颜色。此工具还是一个svg浏览器、查看器...

@Joseph:该库旨在将SVG转换为.NET Path对象。这个设计是没有颜色的,所以你可以(并且必须)设置你喜欢的颜色。这对于现代设计中使用的单色图标非常有用。 如果您想要多彩的图标,您可以组合几个路径(如SvgToXaml演示所示),但我建议使用png文件。这样做可能会失去路径/几何形状的优势:可缩放而不会失去质量。 - BerndK

2

在 Paolo 的错误答案基础上,我进行了改进,成功解决了这个问题。

"MyImage" 类:

Public Class MyImage
    Inherits System.Windows.Controls.Image

    Public Property Color As System.Windows.Media.SolidColorBrush

End Class

在资源字典中,将DrawingImage分配给MyImage样式的Source setter:
<Style TargetType="{x:Type local:MyImage}" x:Key="Bell">
        <Setter Property="Source">
            <Setter.Value>
                <DrawingImage>
                    <DrawingImage.Drawing>
                        <DrawingGroup Opacity="1">
                            <DrawingGroup.Children>
                                <DrawingGroup Opacity="1">
                                    <DrawingGroup.Children>
                                        <DrawingGroup Opacity="1">
                                            <DrawingGroup.Children>
                                                <GeometryDrawing
                                                    Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyImage}}, Path=Color}"
                                                    Pen="{x:Null}" />
                                            </DrawingGroup.Children>
                                        </DrawingGroup>
                                    </DrawingGroup.Children>
                                </DrawingGroup>
                            </DrawingGroup.Children>
                        </DrawingGroup>
                    </DrawingImage.Drawing>
                </DrawingImage>
            </Setter.Value>
        </Setter>
</Style>

在窗口的XAML文件中:

<Window
    ...
    xmlns:local="clr-namespace:AppNameHere">
    <Window.Resources>
        <ResourceDictionary Source="DictionaryName.xaml" />
    </Window.Resources>
    ....
    <Grid Background="Black">
        <local:MyImage Color="Chartreuse" Width="30" Height="30" Style="{StaticResource Bell}" />
    </Grid>
    ...
</Window>

这是结果: http://i.stack.imgur.com/7JNyH.png

0
<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525" >
<Window.Resources>
    <DrawingImage x:Key="Bell1">
        <DrawingImage.Drawing>
            <DrawingGroup Opacity="1">
                <DrawingGroup Opacity="1">
                    <DrawingGroup Opacity="1">
                        <GeometryDrawing  Brush="{Binding Color}" Pen="{x:Null}">
                            <GeometryDrawing.Geometry>
                                <PathGeometry FillRule="Nonzero"  Figures="M 10,100 C 10,300 300,-200 300,100" />
                            </GeometryDrawing.Geometry>
                        </GeometryDrawing>
                    </DrawingGroup>
                </DrawingGroup>
            </DrawingGroup>
        </DrawingImage.Drawing>
    </DrawingImage>
</Window.Resources>
<Grid>
    <local:MyImage DataContext="{Binding ElementName=myImage, Mode=OneWay}" x:Name="myImage"  Color="Red" Source="{StaticResource Bell1}" ></local:MyImage>

</Grid>


0

DrawingImage 将接收与窗口相同的数据上下文,因此您可以将颜色绑定到窗口视图模型上的属性。

Dictionary1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DrawingImage x:Key="Bell">
        <DrawingImage.Drawing>
            <DrawingGroup Opacity="1">
                <DrawingGroup.Children>
                    <DrawingGroup Opacity="1">
                        <DrawingGroup.Children>
                            <DrawingGroup Opacity="1">
                                <DrawingGroup.Children>
                                    <GeometryDrawing Brush="{Binding IconColor}" Pen="{x:Null}">
                                        <GeometryDrawing.Geometry>
                                            <PathGeometry FillRule="Nonzero" Figures="........." />
                                        </GeometryDrawing.Geometry>
                                    </GeometryDrawing>
                                </DrawingGroup.Children>
                            </DrawingGroup>
                        </DrawingGroup.Children>
                    </DrawingGroup>
                </DrawingGroup.Children>
            </DrawingGroup>
        </DrawingImage.Drawing>
    </DrawingImage>
</ResourceDictionary>

MyTestWindow.xaml

<Window x:Class="MyTestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">        
    <Window.Resources>
        <ResourceDictionary Source="Dictionary1.xaml" />
    </Window.Resources>
    <Grid>
        <Image Source="{StaticResource Bell}" />
    </Grid>
</Window>

然后视图模型将需要一个IconColor属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接