【发布时间】:2012-05-18 01:11:09
【问题描述】:
我正在尝试在应用程序中创建一个警告窗口。该窗口需要在单独的线程上运行,并且除其他外还包含一个描绘失败对象的画布。 Canvas 已经存在于主应用程序中,我需要的只是在警告窗口中显示相同的 Canvas。问题是我收到一个错误,说另一个线程拥有该对象。 我尝试使用this 方法进行深层复制,但没有运气。有什么我错过的吗,或者真的没有简单的方法来复制画布或图像集合。或者,是否可以进行深层复制,然后更改复制对象的踏步亲和性?
我应该认为以前有人遇到过这个问题,但是我的搜索技能这次没有给我相关的结果。
提前致谢! -ruNury
编辑 1
private Canvas cloneCanvas()
{
Canvas testcanv = new Canvas();
Dispatcher.Invoke(new Action(delegate
{
var t = SomeViewModel.GetCanvasWithImages();
testcanv = CopyCanvas(t);
}));
return testcanv;
}
public static UIElement DeepCopy(UIElement element)
{
if (element != null)
{
var xaml = XamlWriter.Save(element);
var xamlString = new StringReader(xaml);
var xmlTextReader = new XmlTextReader(xamlString);
var deepCopyObject = (UIElement)XamlReader.Load(xmlTextReader);
return deepCopyObject;
}
return null;
}
private Canvas CopyCanvas(Canvas inputCanvas)
{
if (inputCanvas != null)
{
var outputCanvas = new Canvas();
foreach (UIElement child in inputCanvas.Children)
{
outputCanvas.Children.Add(DeepCopy(child));
}
return outputCanvas;
}
return null;
}
【问题讨论】:
-
只有创建UI对象的线程(main)才能访问UI对象。
-
是的,这就是为什么我需要可以在新线程上显示的对象的副本...
-
我感受到你的痛苦。我试图这样做并放弃了。似乎即使是 UI 对象的副本仍然是 UI 对象。我知道这看起来很极端,但您可能需要序列化为字符串并创建画布。我什至不得不将 FlowDocument 序列化为字符串以将其从后台传递到主目录。
-
烦人的部分是我可以在调度程序中放置一个断点并查看 testcanv 包含正确的数据,但是一旦我在调度程序之外,testcanv 子级就属于另一个线程。 .
-
内部 .NET 只定期检查所有权。