10

视觉工作室 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. 为什么在资源中明确定义纯色画笔似乎可以解决问题?

编辑:

看起来这是 MS 决定不修复的错误(感谢Sheridan的链接):http ://connect.microsoft.com/VisualStudio/feedback/details/589898/wpf-border-borderbrush-does-not-see-动态资源的变化

4

5 回答 5

3

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>

在此处输入图像描述

于 2013-07-22T14:27:12.727 回答
2

显然,您的问题的答案是否定的,这种行为不是错误。

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

DynamicResources 在运行时而不是编译时“查找”。“动态”不是指“可以随时动态更新”,而是“我们稍后会在实际需要时查找”。

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

顺便说一句,这在 StackOverflow 上会是一个很好的问题——“为什么我的 DynamicResource 没有被更新?”

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

于 2013-07-22T15:37:35.407 回答
1

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

    <Rectangle StrokeThickness="20">
        <Rectangle.Stroke>
            <SolidColorBrush Color="{DynamicResource BorderColor}"/>
        </Rectangle.Stroke>
        <Rectangle.Fill>
            <SolidColorBrush Color="{DynamicResource BackgroundColor}"/>
        </Rectangle.Fill>
    </Rectangle>
于 2013-07-22T14:29:42.990 回答
0

它似乎已在 4.5 中修复。就我而言,它适用于 Windows 8,但不适用于 Windows XP(没有 .net 4.5)。

于 2014-04-04T15:34:50.117 回答
0

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

于 2014-11-04T14:50:29.897 回答