2010-03-26 8 views
0

저는 WPF와 MVVM으로 놀고 있습니다. 그리고 네트워크 가용성이 변경 될 때마다 색상을 변경하는 사각형을 표시하는 간단한 앱을 만들었습니다.WPF ViewModel 속성에 바인딩

그러나 그렇게되면, 나는이 오류 얻을 : Cannot use a DependencyObject that belongs to a different thread than its parent Freezable.

코드를

XAML

<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="400" Width="600"> 
<DockPanel LastChildFill="True"> 
    <Rectangle x:Name="networkStatusRectangle" Width="200" Height="200" Fill="{Binding NetworkStatusColor}" /> 
</DockPanel> 
</Window> 

숨김 코드 System.Windows를 사용

; WpfApplication1.ViewModels 사용하기.

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = new NetworkViewModel(); 
     } 
    } 
} 

뷰 모델

using System.ComponentModel; 
using System.Net.NetworkInformation; 
using System.Windows.Media; 

namespace WpfApplication1.ViewModels 
{ 
    public class NetworkViewModel : INotifyPropertyChanged 
    { 
     private Brush _NetworkStatusColor; 

     public Brush NetworkStatusColor 
     { 
      get { return _NetworkStatusColor; } 
      set 
      { 
       _NetworkStatusColor = value; 
       NotifyOfPropertyChange("NetworkStatusColor"); 
      } 
     } 

     public NetworkViewModel() 
     { 
      NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged); 
     } 

     protected void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) 
     { 
      if (e.IsAvailable) 
      { 
       this.NetworkStatusColor = new SolidColorBrush(Colors.Green); 
      } 
      else 
      { 
       this.NetworkStatusColor = new SolidColorBrush(Colors.Red); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

     public void NotifyOfPropertyChange(string propertyName) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

나는 내가 뭔가를 호출하여 NetworkStatusColor 속성을 변경해야한다고 가정?

답변

3

올바르게 가정하십시오. 보고자하는 .Invoke 메서드는 Dispatcher 클래스입니다. 조금이 같은

뭔가 :

if (this.Dispatcher.Thread != Thread.CurrentThread) 
{ 
    this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(...your method...), any, params, here); 
    return 
} 

좀 더 많은 정보를 가진 MSDN article here있다.

+0

차갑다. DispatcherObject 클래스에서 항상 ViewModels을 파생시켜야합니까? – MartinHN

+0

@MartinHN : 아니요, 죄송합니다. viewmodel을 DispatcherObject에서 상속받지 않아도됩니다. 이 코드는보기/창 클래스에서 실행중인 경우에 사용됩니다. 뷰 모델 내에서이를 수행하려면 뷰 모델이 바인딩 (또는 작성) 될 때보기에서 Dispatcher를 전달하면됩니다. 또는 기본 스레드에서 뷰 모델을 만들면 Dispatcher.CurrentDispatcher를 사용할 수 있습니다. viewmodel에서 창 디스패처에 액세스하기위한 다른 제안에 대해이 질문을 살펴보십시오. http://stackoverflow.com/questions/2354438/mvvm-best-practice-to-pass-dispatcher-to-the-viewmodel –

+0

뷰 모델에서 DependencyProperties를 사용하려는 경우 계층에 간접적으로 DispatcherObject를 상속하지 않게됩니다. (부모 클래스 인 DependencyObject입니다.) 그래서 어떻게 작업하는지에 따라 달라집니다. –

0

MVVM을 사용하면 디스패치를 ​​처리 할 때 몇 가지 옵션이 있습니다. 어느 쪽이든 당신에게보기를위한 메시지를 보내서 당신을 위해 작업을 호출하게하거나, 당신이 쉽게 조롱 할 수있는 일종의 추상 디스패처 서비스를 만들 수 있습니다.

사용/복사 할 수있는 간단한 디스패처 서비스가 포함되어 있으므로 MVVM Light 툴킷을 살펴보십시오.

관련 문제