2017-05-12 21 views
0

観測可能なコレクションにデータを挿入すると、コレクション内の新しいデータを「設定」するときに「戻り値」が呼び出されないことがわかります。プログラムの別の場所からデータを設定すると機能しますので、動作する方法のニュアンスを理解していないといけません。動作する部分は、「This works」、「ChooseFile()」の下のコメント付きコードを取り出すときです。デバッガでは、OptionsToChooseに両方のケースでデータがあることがわかります。動作すると、XAMLが正しく更新されます。ObservableCollectionが設定された後に新しいデータを返さない

class ScripterViewModel : BindableBase 
{ 

    public ScripterViewModel() 
    { 
     ScripterModel scripterModel = new ScripterModel(); 

     ObservableCollection<string> tabsChoice = new ObservableCollection<string>(); 
     tabsChoice.Add("Tabs"); 
     tabsChoice.Add("Buttons"); 
     Tabs = tabsChoice; 

     this.OpenFileBtn = new DelegateCommand(chooseFile, canChooseFile).ObservesProperty(() => OpenFile); 
     this.SaveFileBtn = new DelegateCommand(saveFile, canSaveFile).ObservesProperty(() => SaveFile); 

     //This works 
     //var myJSONDoc = JsonConvert.DeserializeObject<JSONclass>(File.ReadAllText(@"C:\Users\mike\Documents\Haas\Scripter\settings.json")); 
     //OptionsToChoose = new ObservableCollection<Tabbed>(myJSONDoc.TabbedBtns); 

    } 
     public void chooseFile() 
    { 
     var myJSONDoc = JsonConvert.DeserializeObject<JSONclass>(File.ReadAllText(@"C:\Users\mike\Documents\Haas\Scripter\settings.json")); 
     OptionsToChoose = new ObservableCollection<Tabbed>(myJSONDoc.TabbedBtns); 

    } 
     public ObservableCollection<Tabbed> _optionsToChoose = new ObservableCollection<Tabbed>(); 
     public ObservableCollection<Tabbed> OptionsToChoose 
    { 
     get 
     { 
      return _optionsToChoose; 
     } 
     set 
     { 
      _optionsToChoose = value; 
     } 
    } 

} 

答えて

2

を参照してください:あなたはすでに次のようにあなたの現在のOptionsToChooseプロパティの実装を置き換えることによって行うことができるので、PropertyChangedイベントを発生させ、BindableBaseを拡張しますビューモデルはビューによって使用されます。

この例では、機能していない例では、ObservableCollectionを消去して項目を追加する代わりに、ObservableCollectionを新しいものに置き換えるだけです。したがって、V.Leonが彼の答えで指摘したように、プロパティが変更されたことを通知する必要があります。

既存のコレクションを消去してjsonの値を入力します。

var myJSONDoc = JsonConvert.DeserializeObject<JSONclass>(File.ReadAllText(@"C:\Users\mike\Documents\Haas\Scripter\settings.json")); 
OptionsToChoose.Clear(); 
foreach (var item in myJSONDoc.TabbedBtns) 
{ 
    OptionsToChoose.Add(item); 
} 
+0

次に、OptionsToを読み込み専用のプロパティを選択する、つまりセッターを削除する必要があります。 – Clemens

+0

はい、すでに初期化されているプラ​​イベートフィールドを公開しているだけなので、それもそうです。 –

+0

XAML側から任意の値を設定していないので、これは私にとってはうまくいくはずです。これはピックリストとしてもっと使われています。 – coolercargo

2

あなたはOptionsToChooseのセッターでPropertyChangedイベントを発生させていません。あなたはそれが初期化されますコンストラクタでOptionsToChooseを作成しているとき

public ObservableCollection<Tabbed> OptionsToChoose 
{ 
    get 
    { 
     return _optionsToChoose; 
    } 
    set 
    { 
     SetProperty(ref _optionsToChoose, value); 
    } 
} 

BindableBase.SetProperty Method

+0

答えをいただきありがとうございます。私が必要としているとおり、他の回答を選択しましたが、参照先のリンクを見ていきます。 – coolercargo

0

理想的には、バインド後にObservableCollectionの参照全体を変更しないでください。その中のアイテムをクリアしてから、新しいアイテムを追加してください。

public ObservableCollection<Tabbed> _optionsToChoose = new ObservableCollection<Tabbed>(); 
public ObservableCollection<Tabbed> OptionsToChoose 
{ 
    get 
    { 
     return _optionsToChoose; 
    } 
} 

OptionsToChoose.Clear(); 
OptionsToChoose.Add(foo); 
+0

downvoterからのコメントを待っています。 –

-1

あなたのコードでは、コレクションをリセットする場合は、コレクションのプロパティをPropertyChangedにする必要があります。つまり、ObservableCollectionは実際には理想的なコレクションタイプではありません。私がお勧めすることは、プロジェクトのMvvmHelpers含むとあなたがそこに利点のカップルを取得ObservableRangeCollection

public class MyPageViewModel : BindableBase 
{ 
    public MyPageViewModel() 
    { 
     OptionsToChoose = new ObservableRangeCollection<Tabbed>(); 
     SomeCommand = new DelegateCommand(OnSomeCommandExecuted); 
    } 

    public DelegateCommand SomeCommand { get; } 

    public ObservableRangeCollection<Tabbed> OptionsToChoose { get; } 

    private void OnSomeCommandExecuted() 
    { 
     // get some updated data 
     IEnumerable<Tabbed> foo = DoFoo(); 
     OptionsToChoose.ReplaceRange(foo); 
    } 
} 

を使用しています。 1つはあなたのコレクションを割り当てたり、割り当てを解除したりしていません。また、ObservableRangeCollectionはPropertyChangedイベントまたはCollectionChangedイベントを発生させる前に完全なリストを更新します。これにより、UI通知が少な​​くなり、アプリケーションのパフォーマンスが向上します。

関連する問題