2017-05-12 12 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

를 참조하십시오 뷰 모델은 뷰에서 사용됩니다.

작동하지 않는 예제에서는 ObservableCollection을 지우고 항목을 추가하는 대신 ObservableCollection을 새로운 것으로 바꾼 것입니다. 그러므로 V. 레이온 (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

예, 이미 초기화 된 private 필드를 노출하고 있기 때문에. –

+0

XAML 측에서 any 값을 설정하지 않아서 고맙습니다. 이것은 선택 목록으로 더 많이 사용되고 있습니다. – coolercargo

2

당신은 OptionsToChoose의 세터에 PropertyChanged 이벤트를 발생하지 않습니다. 이미 BindableBase을 확장, 그래서 PropertyChanged 이벤트를 발생하는과 현재 OptionsToChoose 속성 구현을 대체하여 수행 할 수있는 다음과 같은 : 당신이 때 초기화됩니다 생성자에서 OptionsToChoose을 만들 때

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

BindableBase.SetProperty Method

+0

답변을 주셔서 감사합니다. 필요한 답변을 모두 선택 했으므로 참조 된 링크를 살펴 보겠습니다. – coolercargo

0

이상적으로는 바인딩 된 ObservableCollection의 전체 참조를 변경하면 안됩니다. 대신 항목을 지우고 새 항목을 추가하십시오. 이미 당신이 컬렉션을 재설정 한 경우 컬렉션의 속성을하여 PropertyChanged를 인상 할 필요가 코드 주어진 제기 한 바와 같이

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

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

downvoter의 의견 대기 중입니다. –

-1

. 그건 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 ​​알림이 적고 응용 프로그램 성능이 향상됩니다.