2017-08-31 20 views
0

コンボボックスに問題があります。どういうわけか、それは自分自身と同期しなくなる可能性があります。たとえば、BlockSequenceFieldsを変更すると、ドロップダウン・テキストのみが変更されます。下のフィールド1は更新されましたが、現在選択されている項目に反映されていないことがわかります。WPFコンボボックスは現在選択されているアイテムを更新しません

enter image description here

マイIsSynchronizedWithCurrentItem = trueが期待どおりに動作し、現在選択されている項目をしなければならないが、動作するようには思えません。現在の項目が一致しないが、IsSynchronizedWithCurrentItemをtrueに設定し、問題を修正した多くのstackoverflow投稿を読んだ。

これは私のために働いていない理由を誰でも説明できますか?

<ComboBox x:Name="SequenceFieldComboBox" 
       SelectedItem="{Binding BlockSequenceFieldIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
       ItemsSource="{Binding BlockSequenceFields, UpdateSourceTrigger=PropertyChanged}" 
       IsSynchronizedWithCurrentItem="True"> 

     <ComboBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <CheckBox 
         IsChecked="{Binding IsCalibrated, Mode=OneWay}" 
         IsEnabled="False"> 
        </CheckBox> 
        <TextBlock 
         Text="{Binding}"> 
        </TextBlock> 
       </StackPanel> 
      </DataTemplate> 
     </ComboBox.ItemTemplate> 
    </ComboBox> 

編集:ここで氏チェンバレン

// ViewModelBase implements INotifyPropertyChanged 
public class BlockFieldViewModel : ViewModelBase 
{ 
    public BlockSequenceField SequenceField { get; set; } 

    public List<BlockSequenceCalibrationItemViewModel> Calibrations => this.SequenceField?.CalibrationList; 

    public bool IsCalibrated => this.Calibrations.TrueForAll(x => x.IsCalibrated == null || x.IsCalibrated == true); 

    public double AmplitudeThreshold => this.Calibrations.Max(x => x.Amplitude); 

    public int FieldNumber { get; set; } 

    public override string ToString() 
    { 
     string ret = string.Format(CultureInfo.CurrentCulture, "Field {0} ", this.FieldNumber); 

     if (Math.Abs(this.AmplitudeThreshold) > .00001) 
     { 
      ret = string.Concat(ret, string.Format(CultureInfo.CurrentCulture, "({0} mA)", this.AmplitudeThreshold)); 
     } 

     return ret; 
    } 
} 

と大のviewmodelがあるためさらなる詳細は、MainViewModel.csそれを呼び出します。 FieldNumberが更新されたときにBlockFieldViewModelはINPCを上げていないため、ここではクラス内の関連するフィールド

private ObservableCollection<BlockFieldViewModel> blockSequenceFields; 

    public ObservableCollection<BlockFieldViewModel> BlockSequenceFields 
    { 
     get => this.blockSequenceFields; 
     set 
     { 
      this.blockSequenceFields = value; 
      this.OnPropertyChanged("BlockSequenceFields"); 
     } 
    } 

    private void RefreshFieldList() 
    { 
     // In order for the combo box text to update, we need to reload the items 
     var savedIndex = this.BlockSequenceFieldIndex; // to restore to current field. 
     var fieldList = this.CalibrationViewModel.FieldViewModels; 
     this.BlockSequenceFields = new ObservableCollection<BlockFieldViewModel>(fieldList); 
     this.BlockSequenceFieldIndex = savedIndex; 
    } 
+0

コンボボックスのDataContextが設定されているビューモデルを表示してください。あなたの 'public' ObserveableCollectionの' T'クラスのコードを探しています。 BlockSequenceFields {get;} } ' –

+0

あなたのviewModelにINotifyPropertyChangedインターフェースを追加するのを忘れたのでしょうか? – Demon

+0

@ScottChamberlain私は、datacontextがコンボボックスアップデートの一部として正しく設定されていることはかなり確信しています。しかし、明示的にdatacontextを設定し、それが動作するかどうかを確認します。私はdatacontextを設定するファイルの背後にコードがないので、xamlでそれを行うつもりです。 – user2619824

答えて

1

であるあなたの問題が発生しています。そのプロパティのために最小限にする必要があります。

//Assuming the base class looks like 
public class ViewModelBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 


public class BlockFieldViewModel : ViewModelBase 
{ 
    //... 

    public int FieldNumber 
    { 
     get 
     { 
      return _fieldNumber; 
     } 
     set 
     { 
      if(_fieldNumber.Equals(value)) 
       return; 

      OnPropertyChanged(); 
     } 
    } 
    //... 
} 

これはあなたが名前を表示するには.ToString()を使用していることに起因し、あなたの問題を解決したりしません場合、私は確かに知りません。あなたは

public int FieldNumber 
{ 
    get 
    { 
     return _fieldNumber; 
    } 
    set 
    { 
     if(_fieldNumber.Equals(value)) 
      return; 

     //Refresh all properties due to the .ToString() not updating. 
     OnPropertyChanged(""); 
    } 
} 

また、あなたのOnPropertyChangedをメソッドに空の文字列を渡すことで、それはオブジェクト全体のために変更されたプロパティをトリガ解決しない以上見つかった場合、もしList<BlockSequenceCalibrationItemViewModel> Calibrationsは、追加またはから削除、または.Amplitudeは可能性がありすることができますあなたもそれから名前のリフレッシュを引き起こす必要がある変更されました。

+0

@ user2619824 'BlockSequenceCalibrationItemViewModel'と' BlockSequenceField'のコードを追加することができましたか、私はそのような問題をすべて解決する完全な例を作ることができます。 –

関連する問題