DynamicResource颜色不适用于边框上的BorderBrush - Bug?

时间:2013-07-22 14:05:30

标签: wpf c#-4.0 border dynamicresource

Visual Studio 2010 | .NET / WPF 4.0

我认为这可能是一个WPF错误,但我似乎无法找到有关它的错误报告。为了弥补我错过一些明显的东西的可能性,我转向stackoverflow寻求答案!

考虑这个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”,它会在运行时正确呈现。这种不一致真的让我烦恼,我无法弄明白。\

所以:

  1. 为什么DynamicResource不适用于BorderBrush?
  2. 鉴于#1,为什么 它适用于背景?
  3. 为什么在资源中明确定义纯色画笔似乎可以修复问题?
  4. 编辑:

    看起来这是MS决定不修复的错误(感谢Sheridan链接):http://connect.microsoft.com/VisualStudio/feedback/details/589898/wpf-border-borderbrush-does-not-see-changes-in-dynamic-resource

5 个答案:

答案 0 :(得分:2)

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>

enter image description here

答案 1 :(得分:2)

显然,你的问题的答案是否定的,这种行为是一个错误。

此问题已由用户发布在Microsoft Connect网站上,并给出了以下回复:

  

DynamicResources在运行时“查找”而不是编译时。   “动态”不是指“可以随时动态更新”   但是“我们会在以后查找,当它真的需要时。”

     

如果要在运行时更改边框画笔,则需要   将一个Name =“”属性应用于边框,以便从中触摸它   代码隐藏,或者您可以使用Binding来设置画笔的值   DependencyProperty(如果您正在使用MVVM模式或其他东西   类似)。更改属性,边框画笔由更新   绑定系统。

     顺便说一下,这对StackOverflow来说是一个很好的问题 - “为什么   是不是我的DynamicResource正在更新?“

就个人而言,我最喜欢最后一行。微软最有用的!该页面可以找到here

答案 2 :(得分:1)

另一个有趣的事情是,当使用Rectangle而不是Border时不会发生这种情况。

    <Rectangle StrokeThickness="20">
        <Rectangle.Stroke>
            <SolidColorBrush Color="{DynamicResource BorderColor}"/>
        </Rectangle.Stroke>
        <Rectangle.Fill>
            <SolidColorBrush Color="{DynamicResource BackgroundColor}"/>
        </Rectangle.Fill>
    </Rectangle>

答案 3 :(得分:0)

似乎在4.5中已修复。在我的情况下,它适用于Windows 8,但不适用于Windows XP(没有.net 4.5)。

答案 4 :(得分:0)

这是一个自定义控件,您可以使用它来代替Border。它解决了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表现出同样的问题。