请帮我提供以下任务的建议或演示代码:
我在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;
}
}
}
}
所以我的问题是如何传递将在常量循环中的另一个线程上更改的属性。
答案 0 :(得分:3)
通过传递父对象,您应该有权访问该属性进行更改;但是,在执行此操作之前,您可能希望切换回UI线程(Dispatcher.Invoke),因为“观察者”模型的跨线程变异很少会很好地结束。
另一种方法是让您的代码简单地引发事件(与此属性无关),并让您的UI代码切换到UI步骤并更新视图模型。这种方法将UI代码与“执行”代码完全分开(因为“执行”代码不知道视图模型或线程),并且在需要支持任意UI模型时特别有用。