0

私は WPF とバインディングが初めてで、配列要素とコントロールの間で双方向バインディングを行う方法があるかどうかを確認したかったのです。

私の ViewModel には、次のようなプロパティがあります。

public ObservableCollection<MeaseurementValue> MeasurementValues
        {
            get
            {
                return Config.MeasurementValues;
            }
            set
            {
                if (value == null) return;
                Config.MeasurementValues = value;
                OnPropertyChanged("MeasurementValues");
                QpatConfig.SerializeConfigFile(Config,
                    Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System)) + "//Qualcomm//QPAT//qpat.config");              
            }
        }

MeasurementValues は次のように定義されます。

public class MeaseurementValue
    {
      public string TestName { get; set; }
      public int value { get;set; }
    }

Xaml は次のようになります。

 <TextBox HorizontalAlignment="Left" Grid.Column="1"   Grid.Row="1"   Height="23" Margin="14,20,0,0" TextWrapping="Wrap" Text="{Binding MeasurementValues[0].value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="124"  />

したがって、xaml の要素は ViewModel の Arrayelement にバインドされます。しかし、テキスト コントロールでそのプロパティを変更すると、ViewModel のセッターが呼び出されません。

また、配列内のすべての要素も通知可能になるようにコードを変更したため、次のようになります。

public class MeaseurementValue : INotifyPropertyChanged
    {
      public event PropertyChangedEventHandler PropertyChanged;
      public string TestName { get; set; }    

      private int _value;
      public int value
      {
          get { return _value; }
          set { _value = value; OnPropertyChanged("value"); }
      }

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

しかし、それもうまくいきませんでした

プリミティブ型とは対照的に、配列で行う必要があることは何か違いがありますか?

4

1 に答える 1

2

セッターが呼び出されますが、期待するものではありません。双方向バインディングでは、パスの最後のプロパティのみが更新されます (ターゲット -> ソース方向)。

次のように考えてみてください。C# で記述した場合、何が起こると思いますか?

MeasurementValues[0].value = 1;

ここで何が起こるかというと、最初にMeasurementValues getterが呼び出され、次に配列インデクサーのgetterが呼び出されますが、settervalueプロパティのものです。したがって、配列のセッターが呼び出される理由はありません。あなたはMeasurementValuesセッターから離れた2つのプロパティアクセサーです。書いても

MeasurementValues[0] = new MeasurementValue();

セッターはMeasurementValues呼び出されません。それだけ

MeasurementValues = new ObservableCollection<MeaseurementValue>();

あなたが参照しているセッターが呼び出されます。バインディングとまったく同じです。プロパティ パスの最後の項目は、双方向バインディングで使用される唯一のセッターです。あなたの場合、それはvalueプロパティです。

プロパティが設定されるたびに構成を保存する場合valueは、次のことができます。

  • ValueChangedでイベントを作成し、MeaseurementValue各アイテムを作成するときにそれをフックします
  • 何らかのパブ/サブ メカニズム (Prism のEvent Aggregatorなど) を使用して、値が変更されたことを公開します。
于 2013-10-07T22:03:35.777 に答える