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 - 错误?的主要内容,如果未能解决你的问题,请参考以下文章

边框半径不适用于更宽的屏幕

为视图添加边框不适用于 ipad

JTextField 边距不适用于边框

Apple Vision – 条码检测不适用于不同颜色的条码

按钮按下动画不适用于边框半径

调整输入类型搜索的边框半径不适用于移动 safari