我的情况:
我想绘制一个由不同图层组成的地图。
到目前为止,我使用ItemsControl
来显示所有图层:
<ItemsControl ItemsSource="{Binding Layers}"
ItemTemplate="{StaticResource LayerViewTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我使用的模板如下所示:
<DataTemplate x:Key="LayerViewTemplate"
DataType="{x:Type data:InformationLayer}">
<Path StrokeThikness="{Binding W}"
Stroke="Black"
Data = {Binding Data}/>
</DataTemplate>
如您所见,类InformationLayer
包含一个图层的所有数据。这包括财产:
public GeometryGroup Data { get; protected set; }
生成图层是一个漫长的过程。 我必须阅读一堆文件等。 这就是为什么我想在异步函数中做到这一点。
问题:
GeometryGroup对象属于创建它们的线程。 因此,如果我使用不同的线程来创建我的图层,它们将属于该线程。 我希望它们属于我的主要线程,因为我想将它们用作绑定源。 是否有可能将GeometryGroup从一个线程移动到另一个线程?
到目前为止,生成我的图层的功能如下所示: 但最后一行抛出一个异常,因为wpf不想绑定到一个在另一个线程中生成的对象。
protected async void generateLayers()
{
var progress = new Progress<RefreshLayersProgressReport>(ReportLayerProgress);
var ans = await Task.Run(() => refreshLayers(progress));
Layers = ans;
}
答案 0 :(得分:1)
GeometryGroup
源自Freezable
。因此,在调用Freeze()
方法后,它应该是跨线程可访问的。
来自Freezable页面上的主题安全部分:
当IsFrozen属性为false时,可以使用Freezable对象 只能从创建它的线程访问。试图 从另一个线程访问它会抛出InvalidOperationException。该 Dispatcher.Invoke和Dispatcher.BeginInvoke方法提供支持 用于编组到正确的线程。
当他们的IsFrozen属性为true时,Freezable对象就是 自由线程。有关更多信息,请参阅Freezable Objects Overview。