2

混乱している質問があります。私はMCP(test 70-511 Windows App. Dev. with .Net 4)のために勉強しており、リソースのセクションとコード内のリソースの変更に取り組んでいます。以下は本からの直接の引用です (セルフペーストレーニングキット):

リソースが参照するオブジェクトがコードで変更された場合、そのリソースを使用するオブジェクトは、リソースの参照方法に応じて異なる動作をします。DynamicResourceマークアップで参照されるリソースは、リソースがコードで変更されると、新しいオブジェクトを使用します。StaticResourceマークアップでリソースを参照するオブジェクトは、 Resourcesコレクションから最初に取得したオブジェクトを引き続き使用し、変更を認識しません。

そうは言っても、彼らが取り組んでいる質問の 1 つは、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

それを 2 つの部分に分けてみましょう。

1) ここで参照が変更されます:

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

2) ここでは参照は同じままですが、プロパティ(色)を変更します。

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

フレームワーク (WPF) の背後には、あなたや私が書くことができるような通常のコードがあることを思い出してください。
ここで見られる動作は、ObservableCollection の動作と非常によく似ています。

ObservableCollectionas ItemsSourceofを使用し、ItemsControl次に行う場合:

myBoundObsCollection = new ObservableCollection<object>();

PropertyChangedを発生させない限り、バインディングは更新されません。

これは小さなサンプルで、行を移動するためのテストです:

Mycol = new ObservableCollection<string>();

InitializeComponent()コンストラクターでBefore/Afterを実行し、何が起こるかを確認します。

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 に答える