DataContextを使う際のthisとx:Name指定の違いについて


this.DataContextで値を反映する場合と  
btnA.DataContextで値を反映する場合の違いは何でしょうか。

スレッドでbtnA,btnBを同時に実行した場合thisを使った場合は画面がちらつきました。  
詳しい方がいましたら教えて頂けると助かります。

XAML

[code]

        <Grid>
        <Button x:Name="btnA" Content="{Binding ButtonContentA}" Click="Button_ClickA"/>
        <Button x:Name="btnB" Content="{Binding ButtonContentB}" Click="Button_ClickB"/>
    </Grid>
    
[/code]

C#

[code]

    void Worker_ProgressChangedA(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
        //スレッドの画面再描画でthisを使うと画面がちらつく
        //this.DataContext = new { ButtonContentA =  e.ProgressPercentage };
        btnA.DataContext = new { ButtonContentA = e.ProgressPercentage };
        }
    
    void Worker_ProgressChangedB(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {    
        //this.DataContext = new { ButtonContentB =  e.ProgressPercentage };
        btnA.DataContext = new { ButtonContentB = e.ProgressPercentage };
        }
    
[/code]




DataContext自体を逐次変更するのは正しいスタイルとは言えません。  
this.DataContext自体を変更すると下位のコントロールすべてに変更通知が飛びます。

データバインドを使う場合、DataContextにはINotifyPropertyChangedを実装したオブジェクトを代入し使いまわしましょう。データバインドしたコントロールはプロパティの変更を常に監視しています。変更通知を投げればコントロール側も変更を追従します。

[code]

    // NotificationObjectは実装を探して見てください。ここでは割愛します。
    public class SamplePresenter : NotificationObject
    {
        public int ButtonContentA
        {
            get { return _ButtonContentA; }
            set
            {
                if (_ButtonContentA != value)
                {
                    _ButtonContentA = value;
                    // ここでPropertyChangedEventArgs("ButtonContentA")が
                    // 通知されると思ってください
                    RaisePropertyChanged("ButtonContentA");
                }
            }
        }
        private int _ButtonContentA;
    }
    
    public partial class SampleWindow : Window
    {
        // 少し手抜きですが以下のようにバインドされていたとして
        public SampleWindow() {
            this.DataContext = Presenter = new SamplePresenter();
        }
        public SamplePresenter Presenter { get; set; }
    
        void Worker_ProgressChangedA(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
            //スレッドからPresenterの値を更新します
            this.Presenter.ButtonContentA = e.ProgressPercentage;
        }
    }
    
[/code]




DataContext自体を逐次変更するのは正しいスタイルとは言えません。  
this.DataContext自体を変更すると下位のコントロールすべてに変更通知が飛びます。

データバインドを使う場合、DataContextにはINotifyPropertyChangedを実装したオブジェクトを代入し使いまわしましょう。データバインドしたコントロールはプロパティの変更を常に監視しています。変更通知を投げればコントロール側も変更を追従します。

[code]

    // NotificationObjectは実装を探して見てください。ここでは割愛します。
    public class SamplePresenter : NotificationObject
    {
        public int ButtonContentA
        {
            get { return _ButtonContentA; }
            set
            {
                if (_ButtonContentA != value)
                {
                    _ButtonContentA = value;
                    // ここでPropertyChangedEventArgs("ButtonContentA")が
                    // 通知されると思ってください
                    RaisePropertyChanged("ButtonContentA");
                }
            }
        }
        private int _ButtonContentA;
    }
    
    public partial class SampleWindow : Window
    {
        // 少し手抜きですが以下のようにバインドされていたとして
        public SampleWindow() {
            this.DataContext = Presenter = new SamplePresenter();
        }
        public SamplePresenter Presenter { get; set; }
    
        void Worker_ProgressChangedA(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
            //スレッドからPresenterの値を更新します
            this.Presenter.ButtonContentA = e.ProgressPercentage;
        }
    }
    
[/code]

