如何在多个线程中使用副本(或相同)对象

时间:2012-05-09 13:48:12

标签: c# wpf canvas copy clone

我正在尝试在应用程序中创建一个警告窗口。窗口需要在单独的线程上运行,并且包含描绘失败对象的Canvas。 Canvas已经存在于主应用程序中,我需要的只是在警告窗口中显示相同的Canvas。问题是我得到一个错误,说另一个线程拥有该对象。 我尝试使用this方法进行深层复制,但没有运气。有什么我错过了,或者真的没有简单的方法来复制Canvas或图像集合。或者,是否可以执行深层复制,然后更改复制对象的踩踏亲和力?

我认为之前有人遇到过这个问题,但这次我的训练技巧没有给我带来任何相关的结果。

提前致谢! -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;
    }

1 个答案:

答案 0 :(得分:0)

您可以使用单例模式来维护一个警告窗口对象。

如果要将画布放入警告窗口,则必须使用Dispatcher

Dispatcher将封送方法调用UI线程。

类似

  warningWindow.Dispatcher.Invoke(
      System.Windows.Threading.DispatcherPriority.Normal,
      new Action(
        delegate()
        {
          myCheckBox.IsChecked = true;
        }
    ));

其中warningWindow将通过单例实例

提供