2017-05-12 42 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通知和更好的应用性能。