2015-02-05 13 views
0

View, Model 및 ViewModel은 기존 MVVM 패턴으로 구현 된 WPF 응용 프로그램을 가지고 있지만 솔루션에는 세 가지 프로젝트가 있습니다.다른 프로젝트에있을 때 SynchronizationContext를 ViewModel에 전달하십시오.

내 ViewModel에

public class MyVM : ViewModelBase 
{ 
    private RelayCommand _runCommand; 
    private AsyncObservebleCollection _messages; 

    public AsyncObservebleCollection<Message> Messages 
    { 
     get 
     { 
      return _messages; 
     } 
     set 
     { 
     _messages = value; NotifyPropertyChanged(); 
     } 
    } 

    public ICommand RunCommand 
    { 
     get 
     { 
      if (_runCommand == null) 
      { 
       _runCommand = new RelayCommand(executeParam => 
        bq.QueueTask(this.ExecuteCommand), 
       canExecuteParam => true); 
      } 
      return _runCommand; 
     } 
    } 
} 

bq.QueueTask (this.ExecuteCommand)에 AsyncObservebleCollection의 구현을 잘 알고있다 -> BackgroundWorker에는 백그라운드 스레드에서 명령을 실행하고 그것은 업데이트 메시지 속성에 분부되는 내 견해.

AsyncObservebleCollection에 UI의 SynchronizationContext가 없기 때문에 스레드 위반 예외가 발생합니다. ViewModel이 뷰에 대해 알지 않아야한다는 것을 알고 있기 때문에 어떻게 문제를 해결할 수 있습니까? UI의 SynchronizationContext를 사용하여 RelayCommand를 비동기 적으로 실행하고 UI를 업데이트하려면 어떻게합니까?

다음
public class YourViewModel { 
public YourViewModel(Action<Action> beginInvoke) 
{ 
    this.BeginInvoke = beginInvoke; 
} 

protected Action<Action> BeginInvoke { get; private set; } 

private void SomeMethod() 
{ 
    this.BeginInvoke(() => DoSomething()); 
} } 

이 클래스 (인스턴스화하는 :

는 디스패처에 액세스 할 수없는 경우, 당신은 당신의 클래스에 BeginInvoke 방법의 대리자를 전달할 수 있습니다 당신에게

답변

0

감사 해당 디스패처에 대한 액세스 권한이 있음) :

var dispatcherDelegate = action => Dispatcher.BeginInvoke(action); 
var viewModel = new YourViewModel(dispatcherDelegate); 
+0

viewmodel에보기의 디스패처를 전달하는 것이 좋습니까? – inside

+0

실제로 발송자가 필요하지 않을 수 있습니다. 뷰 모델의 속성을 뷰의 GUI 요소에 바인딩하면 WPF 바인딩 메커니즘이 디스패처를 사용하여 GUI 스레드에 대한 GUI 업데이트를 자동으로 마샬링합니다. 하지만 상황이 많다면이 작업을 수행해야 할 수도 있습니다. UI에 바인딩 된 ObservableCollection을 상상해보십시오. 작업자 스레드에서 _collection.Add()를 호출하려고합니다. –