DynamicResource 颜色不适用于边框上的 BorderBrush - 错误?
Posted
技术标签:
【中文标题】DynamicResource 颜色不适用于边框上的 BorderBrush - 错误?【英文标题】:DynamicResource color doesn't work for BorderBrush on a Border - Bug? 【发布时间】:2013-07-21 07:26:53 【问题描述】:Visual Studio 2010 | .NET/WPF 4.0
我认为这可能是一个 WPF 错误,但我似乎找不到关于它的错误报告。为了弥补我只是错过了一些明显的东西的可能性,我转向 *** 寻求答案!
考虑这个 xaml(代码隐藏中没有任何内容):
<Window x:Class="DownExpanders.BorderTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BorderTest" Height="300" Width="300">
<Window.Resources>
<Color x:Key="BackgroundColor" R="255" G="0" B="0" A="255"/>
<Color x:Key="BorderColor" R="0" G="0" B="255" A="255"/>
<SolidColorBrush x:Key="BorderColorBrush" Color="DynamicResource BorderColor"/>
</Window.Resources>
<Grid>
<Border BorderThickness="20">
<Border.Background>
<SolidColorBrush Color="DynamicResource BackgroundColor"/>
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="DynamicResource BorderColor"/>
</Border.BorderBrush>
</Border>
<Border Margin="40" BorderBrush="DynamicResource BorderColorBrush" BorderThickness="20"/>
</Grid>
</Window>
在设计器中,它按预期呈现。外边框有一个大的蓝色边框和一个红色背景,内边框有一个大的蓝色边框。太好了。
当我运行代码时,外边框没有边框 - 看起来它只是没有加载。背景正确设置为红色。同时,内边框确实正确加载了它的蓝色边框。
如果我将所有“DynamicResource”更改为“StaticResource”,它会在运行时正确呈现。这种不一致真的很困扰我,我想不通。\
所以:
-
为什么 DynamicResource 不适用于 BorderBrush?
鉴于 #1,为什么 它适用于背景?
为什么在资源中明确定义纯色画笔似乎可以解决问题?
编辑:
看起来这是 MS 决定不修复的错误(感谢 Sheridan 提供链接):http://connect.microsoft.com/VisualStudio/feedback/details/589898/wpf-border-borderbrush-does-not-see-changes-in-dynamic-resource
【问题讨论】:
有趣,在 .net 4.5.50760 中仍然会发生,所以如果这是一个错误,他们还没有修复它。 你肯定会认为这是一个错误。您还可以添加到您的错误报告中,Snoop 将外边框的画笔报告为Transparent
(无错误),如果您直接设置画笔,即使是在BorderBrush="DynamicResource BorderColorBrush"
中的外边框也不会发生此问题。因此,看起来更像是从 DynamicResource Color 创建用于 BorderBrush 的 SolidColorbrush 的问题,它把事情搞砸了。不确定可能是一些尝试锁定资源/访问它们的奇怪案例
哦,我刚刚也看到了其他东西,如果您将资源移动到更高的范围,例如 App.xaml
,它适用于您的确切代码
只是有时动态资源如果没有放在App.xaml
中就不起作用。
【参考方案1】:
RadialGradientBrush 似乎不是这种情况。
<Window x:Class="WpfApplication3.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>
<Grid.Resources>
<Color x:Key="BackgroundColor" R="255" G="0" B="0" A="255"/>
<Color x:Key="BorderColor" R="0" G="0" B="255" A="255"/>
<SolidColorBrush x:Key="BorderColorBrush" Color="DynamicResource BorderColor"/>
</Grid.Resources>
<Border BorderThickness="20">
<Border.BorderBrush>
<RadialGradientBrush>
<GradientStop Color="DynamicResource BorderColor"/>
<GradientStop Color="DynamicResource BorderColor"/>
</RadialGradientBrush>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="DynamicResource BackgroundColor"/>
</Border.Background>
</Border>
<Border Margin="40" BorderBrush="DynamicResource BorderColorBrush" BorderThickness="20"/>
</Grid>
</Window>
【讨论】:
【参考方案2】:显然,您的问题的答案是否定的,这种行为不是错误。
此问题由用户在 Microsoft Connect 站点上发布,并给出了以下回复:
动态资源是在运行时而不是编译时“查找”的。 “动态”不是指“可以随时动态更新” 但是“我们稍后会在实际需要时查找它。”
如果您想在运行时更改边框画笔,您需要 将 Name="" 属性应用于 Border 以便从 代码隐藏,或者您可以使用绑定将画笔的值设置为 一个 DependencyProperty (如果你使用 MVVM 模式或其他东西 相似的)。更改属性,边框画笔将由 绑定系统。
顺便说一句,这在 *** 上会是一个很好的问题——“为什么 我的 DynamicResource 没有更新吗?”
就个人而言,我最喜欢最后一行。微软最有用!该页面可以找到here。
【讨论】:
如果这是一致的行为,我会接受来自 Microsoft 的回复。背景加载得很好。只有 BorderBrush 有问题。事实上,那个 bug 的 OP 也注意到了同样的事情,MS 的回应是“我们没有修复它”。废话,我想这就是答案。为您提供查找错误报告的复选标记:P 我创建了一个简单的解决方法:***.com/questions/19427351/…【参考方案3】:另一个有趣的事情是,当使用矩形而不是边框时不会发生这种情况。
<Rectangle StrokeThickness="20">
<Rectangle.Stroke>
<SolidColorBrush Color="DynamicResource BorderColor"/>
</Rectangle.Stroke>
<Rectangle.Fill>
<SolidColorBrush Color="DynamicResource BackgroundColor"/>
</Rectangle.Fill>
</Rectangle>
【讨论】:
【参考方案4】:似乎在 4.5 中已修复。就我而言,它适用于 Windows 8,但不适用于 Windows XP(没有 .net 4.5)。
【讨论】:
【参考方案5】:这是一个自定义控件,您可以使用它来代替边框。它解决了 BorderBrush 属性的问题。它使用矩形,正如另一个答案所示。请注意,此控件可能与使用 Border 控件的性能不匹配,但它确实有效,因此我建议仅在必要时使用它。
<Style TargetType="x:Type controls:BorderFix">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type controls:BorderFix">
<DockPanel x:Name="PART_Container"
Background="TemplateBinding Background"
LastChildFill="True"
UseLayoutRounding="TemplateBinding UseLayoutRounding">
<Rectangle x:Name="PART_LeftBorder"
DockPanel.Dock="Left"
Fill="TemplateBinding BorderBrush"
Width="Binding Path=BorderThickness.Left, RelativeSource=RelativeSource TemplatedParent"/>
<Rectangle x:Name="PART_TopBorder"
DockPanel.Dock="Top"
Fill="TemplateBinding BorderBrush"
Height="Binding Path=BorderThickness.Top, RelativeSource=RelativeSource TemplatedParent"/>
<Rectangle x:Name="PART_RightBorder"
DockPanel.Dock="Right"
Fill="TemplateBinding BorderBrush"
Width="Binding Path=BorderThickness.Right, RelativeSource=RelativeSource TemplatedParent"/>
<Rectangle x:Name="PART_BottomBorder"
DockPanel.Dock="Bottom"
Fill="TemplateBinding BorderBrush"
Height="Binding Path=BorderThickness.Bottom, RelativeSource=RelativeSource TemplatedParent"/>
<ContentPresenter x:Name="PART_Content"/>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
public sealed class BorderFix : ContentControl
static BorderFix()
DefaultStyleKeyProperty.OverrideMetadata(typeof(BorderFix), new FrameworkPropertyMetadata(typeof(BorderFix)));
我们必须这样做的事实非常荒谬。另一个答案表明此错误已在 Windows 8 使用的 .NET 版本中修复。我尚未对此进行测试,但希望这是正确的。 .NET 4.5.51209 也出现了同样的问题。
【讨论】:
以上是关于DynamicResource 颜色不适用于边框上的 BorderBrush - 错误?的主要内容,如果未能解决你的问题,请参考以下文章