我有一个使用Mvvm Light的项目,在线程中,应用程序抛出异常。
必须在与dependencyobject相同的线程上创建dependencysource。
我使用Canvas
,PolyLine
<Canvas Name="canvas1" SizeChanged="canvas1_SizeChanged" >
<Polyline Points="{Binding SegmentPoints}" Stroke="Black" StrokeThickness="1.5"/>
</Canvas>
在我的ViewModel中,我有一个名为SegmentPoints
private PointCollection segmentPoints;
public PointCollection SegmentPoints
{
get { return segmentPoints; }
set {segmentPoints = value;
RaisePropertyChanged("SegmentPoints");
}
}
我有一个Thread
,它在后台运行。
var p = new ParameterizedThreadStart(StartMeassureThread);
Thread t = new Thread(p);
t.Start(package);
在StartMeassureThread
我调用updatePointCollection
函数:
segmentPoints = new PointCollection();
...somecode
RaisePropertyChanged("SegmentPoints");
它引发了一个例外:
用户代码未处理ArgumentException。
内部
protected virtual void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(
this,
new PropertyChangedEventArgs(propertyName));
}
}
有人可以帮帮我吗?非常感谢你提前。
答案 0 :(得分:1)
您无法从UI线程以外的线程更改UI。要进行同步,您可以使用MVVMLight提供的DispatcherHelper.CheckBeginInvokeOnUI
方法:
var value = CreateSegmentPoints();
DispatcherHelper.CheckBeginInvokeOnUI(()=> SegmentPoints = value);
答案 1 :(得分:0)
当后台线程设置SegmentPoint并且View绑定到此属性时,后台线程将用于更改UI。这将导致异常,因为只允许UI线程更新UI。
可以通过在ViewModel的RaisePropertyChanged中切换到View的Dispatcher来进行快速修复。要做到这一点,你需要以某种方式捕获UI线程。例如,将ViewModel附加到View时将其传递给构造函数。
对于更动态的情况,您可能希望订阅View的DataContextChanged并在那里设置正确的线程。