微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有动态Brush属性的DrawingBrush.GeometryDrawing

如何解决具有动态Brush属性的DrawingBrush.GeometryDrawing

我正在尝试通过设置Brush来动态更改GeometryDrawingDrawingBrush的{​​{1}}的情况。

DynamicResource

当我更改应用的配色方案时,我将<DrawingBrush x:Key="Vector.Close" Stretch="Uniform" AlignmentX="Center" AlignmentY="Center"> <DrawingBrush.Drawing> <DrawingGroup> <GeometryDrawing Brush="{DynamicResource Element.Glyph.Strong}" Geometry="F1 M 38.199,40 L 0,1.801 L 1.801,0 L 40,38.199 L 38.199,40 Z"/> <GeometryDrawing Brush="{DynamicResource Element.Glyph.Strong}" Geometry="F1 M 1.801,40 Z"/> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> ResourceDictionaryRemove()Insert()的顺序移动了MergedDictionary

public static void SelectTheme(string id = "Light")
{
    var theme = Application.Current.Resources.MergedDictionaries.FirstOrDefault(f => f.source != null && f.source.ToString().EndsWith($"Colors/{id}.xaml"));

    if (theme == null)
    {
        theme = Application.Current.Resources.MergedDictionaries.FirstOrDefault(f => f.source != null && f.source.ToString().EndsWith("Colors/Light.xaml"));
        UserSettings.All.MainTheme = AppTheme.Light;
    }

    Application.Current.Resources.MergedDictionaries.Remove(theme);
    Application.Current.Resources.MergedDictionaries.Add(theme);
}

例如,在Light.xaml内,我有一个SolidColorBrush

<SolidColorBrush x:Key="Element.Glyph.Strong" Color="#FF231F20"/>

App.xaml内,我导入了两个资源字典(顺序无关紧要,因为资源将移至最后一个位置):

<!--Themes-->
<ResourceDictionary Source="/Themes/Colors/Dark.xaml"/>
<ResourceDictionary Source="/Themes/Colors/Light.xaml"/>

<ResourceDictionary Source="/Resources/Vectors.xaml"/>

<ResourceDictionary Source="/Themes/Button.xaml"/>

该矢量用作自定义Button上的图标。在按钮内部有一个带有大小和对齐方式的Border,矢量被用作Background

Button的定义和用法IconBrush DependencyProperty):

public class ExtendedButton : Button
{
    public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon),typeof(Brush),typeof(ExtendedButton));

    public Brush Icon
    {
        get => (Brush)GetValue(IconProperty);
        set => SetCurrentValue(IconProperty,value);
    }

    //Ctor and other stuff.
}

<n:ExtendedButton Style="{DynamicResource Style.Button.NoText}" 
                  Icon="{DynamicResource Vector.Close}" Width="30" Padding="6"/>

我将Icon设置为StaticResource,但在测试之前,我改为DynamicResource。但这仍然行不通。

以下是按钮的简化Style

<!--Button • No Border • No Text-->
<Style targettype="{x:Type n:ExtendedButton}" BasedOn="{StaticResource {x:Type Button}}" x:Key="Style.Button.NoText">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate targettype="{x:Type n:ExtendedButton}">
                <Border x:Name="MainBorder" MinHeight="{TemplateBinding MinHeight}" Background="{TemplateBinding Background}">
                    <Grid x:Name="InnerGrid">
                        <Border Background="{TemplateBinding Icon}" Margin="{TemplateBinding Padding}" Opacity="{DynamicResource Element.Opacity}"
                                Height="14" Width="14" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="IsMouSEOver" Value="True">
            <Setter Property="Background" Value="{DynamicResource Brush.Button.Background.Hover}"/>
        </Trigger>
        <Trigger Property="Ispressed" Value="True">
            <Setter Property="Background" Value="{DynamicResource Brush.Button.Background.pressed}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Opacity" Value="0.7"/>
        </Trigger>
    </Style.Triggers>
</Style>

该应用程序的其余部分均有效,更改主题时,其他所有内容都会更改。 Element.Glyph.Strong内部的GeometryDrawing不会更新。

只有在关闭应用程序并再次打开时,它才会以正确的颜色显示矢量,因为它会加载新主题

我猜想Brush属性DependencyProperty也会在资源更新时更新。

我想知道如何在不处理后面代码的情况下将Brush设置为动态颜色?

解决方法

我不确定您是如何更改主题的,但是如果其他组件正在更改,那么我假设您做得正确。

我认为关键是要确保您使用的是 ViewData["CategoriesId"] = new SelectList(_context.Categories,"Id","Titel",ad.CategoriesId); 而不是Background="{DynamicResource Vector.Close}"

Background="{StaticResource Vector.Close}"

Dictionary1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1"> <SolidColorBrush x:Key="Element.Glyph.Strong" Color="Black" /> </ResourceDictionary>

Dictionary2.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1"> <SolidColorBrush x:Key="Element.Glyph.Strong" Color="Yellow" /> </ResourceDictionary>

Dictionary3.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1"> <DrawingBrush x:Key="Vector.Close" Stretch="Uniform" AlignmentX="Center" AlignmentY="Center"> <DrawingBrush.Drawing> <DrawingGroup> <GeometryDrawing Brush="{DynamicResource Element.Glyph.Strong}" Geometry="F1 M 38.199,40 L 0,1.801 L 1.801,0 L 40,38.199 L 38.199,40 Z"/> <GeometryDrawing Brush="{DynamicResource Element.Glyph.Strong}" Geometry="F1 M 1.801,40 Z"/> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> </ResourceDictionary>

MainWindow.xaml

<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Button Background="{DynamicResource Vector.Close}" Width="40" Height="40" VerticalAlignment="Center" Click="ChangeTheme_Click" HorizontalAlignment="Center"/> </Grid> </Window>

MainWindow.xaml.cs

// stuff up here... public string currentDict = "Dictionary1.xaml"; private void ChangeTheme_Click(object sender,RoutedEventArgs e) { if (currentDict == "Dictionary1.xaml") { currentDict = "Dictionary2.xaml"; } else { currentDict = "Dictionary1.xaml"; } var app = (App)Application.Current; app.ChangeTheme(new Uri(currentDict,UriKind.RelativeOrAbsolute)); }

App.xaml

<Application x:Class="WpfApp1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Dictionary1.xaml" /> <ResourceDictionary Source="Dictionary3.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>

App.xaml.cs

显然这有点杂乱无章,但它可以起作用:

Button with black x

Button with yellow x


编辑:

即使使用自定义样式,我也无法复制。这里是切换后:

two buttons,both yellow

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。