首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有动态画笔属性的DrawingBrush.GeometryDrawing

具有动态画笔属性的DrawingBrush.GeometryDrawing
EN

Stack Overflow用户
提问于 2020-09-12 02:59:32
回答 1查看 214关注 0票数 0

我正在尝试通过设置Brush来动态更改DrawingBrush中的GeometryDrawingDynamicResource

代码语言:javascript
复制
<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 L 0,38.199 L 38.199,0 L 40,1.801 L 1.801,40 Z"/>
        </DrawingGroup>
    </DrawingBrush.Drawing>
</DrawingBrush>

当我更改应用程序的配色方案时,我会在MergedDictionary中通过Remove()Insert()改变ResourceDictionary的顺序

代码语言:javascript
复制
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

代码语言:javascript
复制
<SolidColorBrush x:Key="Element.Glyph.Strong" Color="#FF231F20"/>

App.xaml中,我导入了两个资源字典(顺序并不重要,因为资源将被移到最后一个位置):

代码语言:javascript
复制
<!--Themes-->
<ResourceDictionary Source="/Themes/Colors/Dark.xaml"/>
<ResourceDictionary Source="/Themes/Colors/Light.xaml"/>

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

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

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

Button定义和用法(IconBrush DependencyProperty):

代码语言:javascript
复制
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

代码语言:javascript
复制
<!--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>

应用程序的其余部分可以正常工作,当改变主题时,其他一切都会改变。GeometryDrawing中的Element.Glyph.Strong不会更新。

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

我猜测作为DependencyPropertyBrush属性也会随着资源的更新而更新。

我想知道如何才能将Brush设置为动态颜色,而不必使用后面的代码?

EN

回答 1

Stack Overflow用户

发布于 2020-09-12 03:43:03

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

我认为关键是要确保你使用的是Background="{DynamicResource Vector.Close}"而不是Background="{StaticResource Vector.Close}"

Dictionary1.xaml

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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 L 0,38.199 L 38.199,0 L 40,1.801 L 1.801,40 Z"/>
            </DrawingGroup>
        </DrawingBrush.Drawing>
    </DrawingBrush>
</ResourceDictionary>

MainWindow.xaml

代码语言:javascript
复制
<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

代码语言:javascript
复制
// 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

代码语言:javascript
复制
<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

代码语言:javascript
复制
public void ChangeTheme(Uri uri)
{
    var dict = new ResourceDictionary() { Source = uri };
    var dict2 = new ResourceDictionary() { Source = new Uri("Dictionary3.xaml", UriKind.RelativeOrAbsolute) };
    Resources.MergedDictionaries.Clear();
    Resources.MergedDictionaries.Add(dict);
    Resources.MergedDictionaries.Add(dict2);
}

显然,这有点麻烦,但它是有效的:

编辑:

即使使用自定义样式,我也无法重现。这是切换后的结果:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63852845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档