어제부터 다음번에 새로운 복잡성 계층을 추가했습니다. 이론적 인 Model 클래스 인 ViewModel과 View가 있습니다. 내 모델이 threading.Timer의를 가지고 이번에는 (이하 "잘못된"스레드에서 타이머 콜백을 얻기 위해 특별히 선정.INotifyPropertyChanged, ObservableCollection, Threads 및 MVVM
모델은 ObservableCollection에 있습니다. 타이머 콜백 컬렉션에 항목을 추가합니다.
는뷰 모델은 단순히 통과 컬렉션에 바인딩 된 목록 상자가 들어있는보기에 컬렉션.
이 작동하지 않습니다.
이 모델은 같은 타이머 콜백에 업데이트되는 문자열을 제공합니다.
이것 역시 뷰 모델을 통해 노출되고 TextBox에 바인딩됩니다.
이것은 작동합니다.
Google 검색에서 힌트를 보았을 때 컬렉션을 업데이트해도 INotifyCollectionChanged가 예상대로 작동하지 않는다는 것을 알았습니다. 나는 총 내파를 얻었는데, 심지어 예외도 아니고, 응용 프로그램을 즉각적으로 종료합니다.
하나는 어제 우리의 토론에 관한 것이다
그래서 두 가지 질문이 있습니다. 내가보기에 일을하기 때문에 나는 내 모델에서 INotifyPropertyChanged와 ObservableCollections를 사용하고있다. 이러한 메커니즘을 사용하여 내 뷰 모델 또는 기본 모델이 변경된 사항을 알리는 것은 여전히 의미가 있습니다. 그렇다면 다른 스레드에서 발생하는 업데이트를 어떻게 처리합니까?
둘째, INotifyPropertyChanged가 바인딩과 함께 작동하게되는 이유는 무엇입니까? Text라는 DependencyProperty에 문자열 속성을 바인딩하고 있으므로 DependencyProperty 시스템에서 UI 스레드에 대한 내 변경 사항을 마샬링합니다. 편집 : 그리고 나는 그것을 의지 할 수 있습니까? 예를 들어, 제가 크로스 스레드에 대해 이야기 할 것을 기대하기 때문입니까, 아니면 내가 의지해서는 안되는 것을 잡을 수 있습니까?
ListBox는 ItemsSource = "{Binding ObsCollection}"을 통해 바인딩됩니다. 이 때 응용 프로그램이 충돌합니다. 사실, 처음에는 윈도우의 DataContext를 설정되었을 때 무슨 일이 있었 모델이 생성 된 타이머를 시작, 그래서 사실은 ... 비주얼 스튜디오 폭탄
감사
멋지다.하지만 MVVM 관점에서이를 처리하는 "올바른"프로세스는 무엇입니까? 따라서 내 모델의 스레드가 컬렉션을 업데이트하고 있습니다. 내 모델은 이제 Dispatcher에 대해 알고 있어야합니까? 그것은 틀린 것처럼 보인다. 이는 ViewModel을 모델과 뷰 사이의 정확한 분리에 대처할 수 있도록 무겁게 만들 것을 제안합니다. 말이 돼? – Ian
'올바른'접근법이 없습니다. 그러나, 내 개인적인 취향은 ViewModel이 의존하는 간단한 인터페이스 인 IMarshalledInvoker를 만드는 것입니다. IMarshalledInvoker는 다른 스레드에서 일부 동작을 호출하는 단일 메서드를 가지고 있습니다. ViewModel을 뷰와 결합하면 Dispatcher를 커버 아래에 사용하는 IMarshalledInvoker를 생성합니다. 이 패턴을 사용하면 여전히 단위 테스트를 할 수 있으며 여전히 디자이너 지원을 할 수 있습니다. 즉, MVVM입니다 .-) – ColinE
아, 이제 상황이 함께합니다. 교묘하게도 내가 고려하지 않은 방식으로 서로 관련이있는 서로 다른 지식의 비트가 있습니다. 우선 스레드 안전 컬렉션을 만드는 것이 까다로운 일임을 알고 있습니다. 나는 그것을 잊어 버렸고 내 머리 속에서 협회를 만들지 않았다 ... 본질적으로 나는 오직 하나의 실에만 추가하고있다. 재밌는 당신이 왜 당신이 일을하는지 잊어 버렸습니다. 그래서 대답의 핵심은 여러 스레드의 변경 사항을 단일 스레드로 퍼팅하는 것이라고 생각합니다. 뷰와 뷰 모델 사이에 단일 채널이 있습니까? – Ian