2017-05-12 44 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將在初始化時視圖使用視圖模型。

在不起作用的示例中,您只需將新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

然後,您還應該使OptionsToChoose爲只讀屬性,即刪除setter。 – Clemens

+0

是的,因爲它只是暴露已經初始化的私人領域。 –

+0

謝謝,這應該適用於我,因爲我沒有設置XAML方面的任何值。這更多地用作選擇列表。 – coolercargo

2

你是不是在提高的OptionsToChoose二傳手PropertyChanged事件。你已經擴展BindableBase,所以提高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); 
    } 
} 

你得到幾個好處在那裏。一個你不分配和釋放你的收藏。此外,ObservableRangeCollection會在引發PropertyChanged或CollectionChanged事件之前更新完整列表,這會導致一些UI通知和更好的應用性能。