XAML SVG颜色在运行时发生变化

时间:2022-11-24 17:59:06

We have a set of SVGs stored within a resource dictionary.

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

Example:

例子:

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

If you noticed the GeometryDrawing Brush is set to #ff000000 (black). The problem we face is allowing a view to display this SVG and assign the color at runtime (via binding)

如果您注意到几何绘图刷设置为#ff000000(黑色)。我们面临的问题是允许视图显示SVG并在运行时分配颜色(通过绑定)

Our Window (view) has the Resource Dictionary with the icons inside of the Window.Resources.

我们的窗口(视图)具有资源字典,其中包含windows . resources中的图标。

We are looking for a solution like so:

我们正在寻找这样的解决方案:

<Image Source="{StaticResource Bell}" Fill="#FF884422"/>

4 个解决方案

#1


0  

By building on top of Paolo's non-working answer, I was able to solve this.

在保罗的不工作答案的基础上,我解决了这个问题。

The "MyImage" class:

“模板”类:

Public Class MyImage
    Inherits System.Windows.Controls.Image

    Public Property Color As System.Windows.Media.SolidColorBrush

End Class

Inside the resource dictionary, assign the DrawingImage to the Source setter of a MyImage style:

在资源字典中,将DrawingImage分配给MyImage样式的源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}">

with the rest of it following as you'd expect.

剩下的部分如你所料。

Inside the window's XAML file:

在窗口的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>

Here's the result: http://i.stack.imgur.com/7JNyH.png

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

#2


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>

#3


0  

The DrawingImage will receive the same datacontext as the window, so you can bind the color to a property on the window's view model.

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

Dictionary1.xaml

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

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>

Then the view model will need an IconColor property.

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

#4


0  

Have a look at this tool: https://github.com/BerndK/SvgToXaml

看看这个工具:https://github.com/BerndK/SvgToXaml

It can convert all svg's automatically to one xaml. The colors are separated and can be set for all images at once or just for a single image. Sample code for changing colors during runtime is included.

它可以将所有svg自动转换为一个xaml。颜色是分开的,可以一次设置所有的图像,也可以只设置一个图像。包含了在运行时更改颜色的示例代码。

The tool is also a svg browser, viewer ...

该工具也是一个svg浏览器,查看器……

#1


0  

By building on top of Paolo's non-working answer, I was able to solve this.

在保罗的不工作答案的基础上,我解决了这个问题。

The "MyImage" class:

“模板”类:

Public Class MyImage
    Inherits System.Windows.Controls.Image

    Public Property Color As System.Windows.Media.SolidColorBrush

End Class

Inside the resource dictionary, assign the DrawingImage to the Source setter of a MyImage style:

在资源字典中,将DrawingImage分配给MyImage样式的源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}">

with the rest of it following as you'd expect.

剩下的部分如你所料。

Inside the window's XAML file:

在窗口的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>

Here's the result: http://i.stack.imgur.com/7JNyH.png

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

#2


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>

#3


0  

The DrawingImage will receive the same datacontext as the window, so you can bind the color to a property on the window's view model.

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

Dictionary1.xaml

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

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>

Then the view model will need an IconColor property.

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

#4


0  

Have a look at this tool: https://github.com/BerndK/SvgToXaml

看看这个工具:https://github.com/BerndK/SvgToXaml

It can convert all svg's automatically to one xaml. The colors are separated and can be set for all images at once or just for a single image. Sample code for changing colors during runtime is included.

它可以将所有svg自动转换为一个xaml。颜色是分开的,可以一次设置所有的图像,也可以只设置一个图像。包含了在运行时更改颜色的示例代码。

The tool is also a svg browser, viewer ...

该工具也是一个svg浏览器,查看器……