如何解决具有动态Brush属性的DrawingBrush.GeometryDrawing
我正在尝试通过设置Brush
来动态更改GeometryDrawing
中DrawingBrush
的{{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>
中ResourceDictionary
和Remove()
中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
的定义和用法(Icon
是Brush
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
显然这有点杂乱无章,但它可以起作用:
编辑:
即使使用自定义样式,我也无法复制。这里是切换后:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。