0

DataContext の変更について質問があり、この側面を理解するための例を作成します。MainWindow に MainUserControl があります。MainUserControl は、いくつかのユーザー コントロールで構成されます。そのようなユーザー コントロールの 1 つが SubUserControl1 です。

<Window x:Class="WpfApplicationUcBindingQuestion.MainWindow">
    <Grid>
        .....
      <uc:MainUserControl />
    </Grid>
</Window>

<UserControl x:Class="WpfApplicationUcBindingQuestion.MainUserControl">
<Grid>
.....
    <uc:SubUserControl1 x:Name="subUserControl1" />
</Grid>
</UserControl>

MainWindow にはクラス Info のオブジェクトがあります。Class Info は、いくつかの内部クラスで構成されています。それらの 1 つは、たとえば、SubInfo です。Info クラスと SubInfo クラスはどちらも INotifyPropertyChanged を継承しています。

そして、これはそれらのコードです:

public class Info : INotifyPropertyChanged
{
    private SubInfo m_subInfo = new SubInfo();

    public Info()
    {
    }

    public SubInfo SubInfo 
    {
        get
        {
            return m_subInfo;
        }
        set
        {
            m_subInfo = value;
            OnPropertyChanged("SubInfo");
        }      
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    } 
}

public class SubInfo: INotifyPropertyChanged
{
    private string m_subString = "subStr";

    public SubInfo()
    {
    }

    public string SubString 
    {
        get
        {
            return m_subString;
        }
        set
        {
            m_subString = value;
            OnPropertyChanged("SubString");
        }      
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    } 
}

MainUserControl の DataContextをクラス Info のオブジェクトに設定し、SubUserControl1 の DataContext を Info.SubInfo に設定したいと考えています

次のコードはこれを説明しています。

<UserControl x:Class="WpfApplicationUcBindingQuestion.SubUserControl1">
   <Grid>
      .....
    <TextBox Text="{Binding Path=SubString}"/> 
   </Grid>
</UserControl>

public MainUserControl()
{
        InitializeComponent();

        MainWindow mainWnd = (MainWindow)Application.Current.MainWindow;

        Info info = mainWnd.Info;
        this.DataContext = info;

        this.subUserControl1.DataContext = info.SubInfo;
}

新しい subInfo が到着したら、info オブジェクト内の内部オブジェクト subInfo を更新します: (これは MainWindow の機能です)

private void OnUpdateData()
{
    SubInfo arrivedSubInfo = new SubInfo();
    arrivedSubInfo.SubString = "newString";

    m_info.SubInfo = arrivedSubInfo;
}

subUserControl1 の DataContext も変更されることを確認したいと思います。

しかし、それは起こらず、SubUserControl1 内の TextBox は更新されず、「newString」は表示されません。

(注: OnUpdateData() 関数内に次のように記述した場合:

m_info.SubInfo.SubString = arrivedSubInfo.SubString;

(オブジェクト全体ではなく、フィールド-フィールドをコピーします)動作しますが、「50フィールドをコピーしたくない...」

どこが間違っていますか?あなたの助けは本当に感謝されます.

4

1 に答える 1

3

あなたの問題は次のとおりです。

コンストラクターで、それを行うと:

    this.DataContext = info;

    this.subUserControl1.DataContext = info.SubInfo;

DataContext は一度だけ設定します。subUserControl1.DataContext = someNewDataContextつまり、どこかに書かない限り、決して変わらないということです。

これを解決するためにできること:

「適切な解決策」:

バインディングを使用します。XAML で、次のように記述します。

<uc:SubUserControl1 x:Name="subUserControl1" DataContext="{Binding
SubInfo, UpdateSourceTrigger=PropertyChanged}" />

SubInfoプロパティOnPropertyChangedが設定されたときにイベントを発生させると仮定すると、これは機能します。

「醜い解決策」:

必要に応じて、コード ビハインドで明示的に を設定しますUserControlDataContext繰り返しますが、私はそれをお勧めしません。最初の解決策を適用することをお勧めします!

于 2012-09-07T21:01:17.473 に答える