首页 文章

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

提问于
浏览
9

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

所以:

  • 为什么DynamicResource不能用于BorderBrush?

  • 鉴于#1,为什么它适用于背景?

  • 为什么在资源中明确定义纯色画笔似乎可以解决问题?

编辑:

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

5 回答

  • 1

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

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

    DynamicResources在运行时“查找”而不是编译时 . “动态”不是指“可以在任何时间动态更新”,而是“我们会在以后查看它时实际需要它” . 如果要在运行时更改边框画笔,则需要将Name =“”属性应用于Border以便从代码隐藏中触摸它,或者可以使用Binding将画笔的值设置为a DependencyProperty(如果您正在使用MVVM模式或类似的东西) . 更改属性,边框画笔由绑定系统更新 . 顺便说一下,这在StackOverflow上是一个很好的问题 - “为什么我的DynamicResource不会被更新?”

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

  • 0

    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

  • 0

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

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

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

  • 2

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

相关问题