我正在尝试动态更改画笔的颜色。我写了一个非常简单的例子,但我不明白为什么它不起作用。
我在我的应用程序的 ResourceDictionary 中定义了一个前景色和一个使用该颜色作为 DynamicResource 的前景画笔:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Color x:Key="Foreground">#FF0000</Color>
<SolidColorBrush x:Key="ForegroundBrush" Color="{DynamicResource Foreground}" />
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
然后,在我的 Window.xaml 中,我使用画笔设置文本块前景:
<Window x:Class="DictionaryColorTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBlock Name="mTextBlock" Foreground="{DynamicResource ForegroundBrush}">This is just a text block</TextBlock>
<Button Name="Button1" Click="Button1_Click">Change color</Button>
</StackPanel>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
最后在我的代码后面,我改变了颜色:
private void Button1_Click(object sender, RoutedEventArgs e)
{
Application.Current.Resources["Foreground"] = Colors.Green;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,画笔颜色没有更新。有人可以解释一下为什么吗?
注意:我知道,如果直接更改画笔的颜色,效果很好,但我试图理解为什么使用颜色作为动态资源的 SolidColorBrush 在颜色更改时不会更新其颜色。
如果我对文本块使用样式,只需更新颜色,它就可以正常工作并且画笔会采用正确的颜色。直接使用画笔和使用样式有什么区别?
<Style TargetType="TextBlock" x:Key="TextBlockStyle">
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
</Style>
Run Code Online (Sandbox Code Playgroud)
如果没有一个好的最小、完整和可验证的代码示例来可靠地重现您的问题,就不可能确定问题是什么。但基本问题似乎是您试图DynamicResource以不受支持的方式使用。
从文档中:
\n\n\n\n\n动态资源引用有一些显着的限制。至少必须满足以下条件之一:
\n\n\xe2\x80\xa2 所设置的属性必须是 FrameworkElement 或 FrameworkContentElement 上的属性。该属性必须由 DependencyProperty 支持。
\n\n\xe2\x80\xa2该引用适用于 StyleSetter 中的值。
\n\n\xe2\x80\xa2要设置的属性必须是 Freezable 上的属性,该属性作为 FrameworkElement 或 FrameworkContentElement 属性的值或 Setter 值提供。
\n\n由于要设置的属性必须是 DependencyProperty 或 Freezable 属性,因此大多数属性更改都可以传播到 UI,因为属性更改(更改后的动态资源值)会被属性系统确认。大多数控件都包含逻辑,如果 DependencyProperty 发生更改并且该属性可能会影响布局,则该逻辑将强制控件采用另一种布局。但是,并非所有具有 DynamicResource 标记扩展作为其值的属性都保证以在 UI 中实时更新的方式提供值 [强调我的]。该功能仍然可能会根据属性、拥有该属性的类型甚至应用程序的逻辑结构而有所不同。
\n
您正在设置一个SolidColorBrush对象的属性,该属性不是aFrameworkElement或FrameworkContentElement。该场景确实满足文档中的第三点(SolidColorBrush是 a Freezable,并且它Freezable作为 a 的值提供FrameworkElement)。但请注意我用粗体显示的文本。即使满足这些要求,也不能保证它会起作用。
有趣的是,当在a 直接拥有的上下文中完成时,您似乎试图实现的基本方法确实有效(例如)。ResourceDictionaryFrameworkElementWindow
为什么会这样,我不知道。我的猜测是,只要您处于某处的上下文中FrameworkElement ,就有足够的内部状态管理来处理更新DynamicResource代理,因此它可以正常工作。
无论如何,这意味着一种可能的解决方法是将您的资源放入,Window.Resources而不是您现在放置的任何地方。我不知道你是否可以指望它总是有效;毕竟,该文档包罗万象,让微软可以说“也许它会起作用,也许它不会”。但在我看来,这种情况不会很快被打破。
或者,您可以修改画笔资源本身。例如:
\n\nprivate void Button1_Click(object sender, RoutedEventArgs e)\n{\n Application.Current.Resources["ForegroundBrush"] = new SolidColorBrush(Colors.Green);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这确实符合文档中的更多要求,因此似乎更有可能适用于 .NET 的任何未来版本(我已经验证它今天确实有效)。
\n| 归档时间: |
|
| 查看次数: |
4112 次 |
| 最近记录: |