2011-02-05 52 views
3

可以请你帮我咨询或演示代码以下任务:更改视图模型属性从另一个线程

我在WPF程序,该程序在串行端口上不断地听,如果接受了它应该在特定的信号更改ViewModel中的属性。监听器在另一个线程上启动,所以我想知道如何从另一个线程更改ViewModel属性,我尝试通过引用传递属性,但这是不可能的。

public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    //My property in the view model 
    private Boolean _Lock; 
    public Boolean Lock 
    { 
     get { return _Lock; } 
     set 
     { 
      _Lock = value; 
      OnPropertyChanged("Lock"); 
     } 
    } 

//Start the listener thread 
     Thread ComListenThread = new Thread(delegate() 
      {     
       Com cm = new Com(Path,Lock);      
       cm.Start();      
      }); 
     ComListenThread.Start(); 


class Com 
{ 

    private Uri web { get; set; } 
    private Boolean Lock { get; set; } 

    public Com(Uri Path,Boolean _Lock) 
    { 
     web = Path;         
     Lock = _Lock;            
    } 


    public void Start() 
    { 
     try 
     { 
      port = new SerialPort(portName, baudRate, parity, dataBits, stopBits); 

     } 
     catch (Exception e) 
     { 
      MessageBox.Show("Reason {0}:", e.Message); 
     } 

     port.ReadTimeout = 500; 
     port.Open(); 

     int position = 0;    
     while (true) 
     { 

      try 
      { 
       int len = port.Read(data, position, data.Length - position); 
       position += len; 
      } 
      catch (TimeoutException) 
      { 


       //How to change Lock property 
       Lock = (data[2]==5)?true:false; 


       position = 0; 
      } 
     } 
    }      
} 

所以我的问题是如何传递将在另一个线程在恒定循环中更改的属性。

回答

3

通过传递父对象您应该有权访问该属性进行更改;不过,在执行此操作之前,您可能需要切换回UI线程(Dispatcher.Invoke),因为“观察者”模型的交叉线程变异很少能够很好地结束。

另一种方法是让代码简单地引发事件(与此属性无关),并让UI代码切换到UI并更新视图模型。这种方法将UI代码与“执行”代码完全分开(因为“执行”代码对视图模型或线程没有任何认识),如果您需要支持任意UI模型,该方法特别有用。

+0

+1。提高事件会是一个更好的解决方案。 –

相关问题