2

我有一个让我困惑的问题。我正在为我的 MCP 学习(使用 .Net 4 测试 70-511 Windows App. Dev.),并且我在资源部分和更改代码中的资源。这是直接来自书中的引述(自定进度培训套件):

如果资源引用的对象在代码中发生更改,则使用该资源的对象的行为会有所不同,具体取决于引用资源的方式。当资源在代码中更改时,使用DynamicResource标记引用的资源使用新对象。使用StaticResource标记引用资源的对象继续使用它们最初从Resources集合中检索到的对象,并且不知道更改。

话虽如此,他们让您解决的问题之一是 XAML 问题。这是该问题的代码:

<Window x:Class="Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Window1" Height="300" Width="300">
  <Window.Resources>
    <SolidColorBrush Color="Red" x:Key="ForegroundBrush" />
    <SolidColorBrush Color="Blue" x:Key="BackgroundBrush" />
  </Window.Resources>
  <Grid>
    <Button Background="{StaticResource BackgroundBrush}"
       Foreground="{DynamicResource ForegroundBrush}" Height="23"
       Margin="111,104,92,0" Name="Button1"
       VerticalAlignment="Top">Button</Button>
  </Grid>
</Window>

问题是:执行以下代码时,按钮的颜色会发生什么变化?

SolidColorBrush aBrush = new SolidColorBrush(Colors.Green);
this.Resources["ForegroundBrush"] = aBrush;
SolidColorBrush bBrush;
bBrush = (SolidColorBrush)this.Resources["BackgroundBrush"];
bBrush.Color = Colors.Black

答案选择是:

  1. 没发生什么事。
  2. 背景变为黑色。
  3. 前景变为绿色。
  4. 2和3都有。

本书给出的答案是 4 2 和 3。

我的困境/困惑是:如果书中指出动态资源将更改以反映代码中所做的更改,而静态资源将继续使用他们最初检索的对象,那么为什么背景和前景上面代码/XAML 示例中的按钮更改?我已经尝试过了,他们都改变了。

任何帮助,将不胜感激。

4

1 回答 1

1

让我们把它分成两部分:

1)这里的参考改变了

SolidColorBrush aBrush = new SolidColorBrush(Colors.Green);
this.Resources["ForegroundBrush"] = aBrush;

2)这里的参考保持不变,但你改变了一个属性(颜色):

SolidColorBrush bBrush;
bBrush = (SolidColorBrush)this.Resources["BackgroundBrush"];
bBrush.Color = Colors.Black

请记住,在框架 (WPF) 的背后,有像你我一样可以编写的常规代码。
您在此处看到的行为非常类似于 ObservableCollections 的行为:

如果您使用ObservableCollectionas ItemsSourceof an ItemsControl,然后执行以下操作:

myBoundObsCollection = new ObservableCollection<object>();

除非您提出PropertyChanged,否则绑定不会刷新。

这是一个小样本,测试移动线:

Mycol = new ObservableCollection<string>();

在构造函数之前/之后InitializeComponent(),看看会发生什么。

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.DataContext = this;
            Mycol = new ObservableCollection<string>();
            InitializeComponent();

            Mycol.Add("this");
            Mycol.Add("is");
            Mycol.Add("a");
            Mycol.Add("test");
        }

        public ObservableCollection<string> Mycol { get; set; }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Mycol = new ObservableCollection<string>();
            Mycol.Add("??");
        }
    }

和 XAML:

<Window x:Class="ObsColTest.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">
    <StackPanel>
        <ListBox ItemsSource="{Binding Mycol}" />
        <Button Content="Click me!"  Click="Button_Click"/>
    </StackPanel>
</Window>

然后,当您单击按钮时,请注意ListBox它没有更新,即使它必然会彻底改变的集合!

但是,如果您只是修改了集合,那么无论您是否PropertyChanged在集合上提出了新行,都会显示新行。
你的Color财产也是如此SolidColorBrush

DynamicResource 可以解决这个问题:最重要的是,如果您更改资源的任何属性,它将反映在 UI 上,如果您更改引用,它也会反映在 UI 上。

请记住,它使 DynamicResource (稍微?)性能低于 StaticResource ;)

于 2012-07-06T16:21:48.513 回答