是否有一种简单/内置的方法来获取XAML元素的精确副本(克隆)?

Edw*_*uay 14 c# wpf xaml clone

我需要使XAML区域可打印,因此制作此按钮处理程序:

private void Button_Click_Print(object sender, RoutedEventArgs e)
{
    Customer.PrintReport(PrintableArea);
}
Run Code Online (Sandbox Code Playgroud)

在PrintReport中,我将frameworkelement打包到其他元素中,以便以与屏幕上不同的方式打印它,如下所示:

public void PrintReport(FrameworkElement fwe)
{
    StackPanel sp = new StackPanel();
    sp.Children.Add(fwe);
    TextBlock tb = new TextBlock();
    tb.Text = "hello";
    sp.Children.Add(tb);

    PrintDialog dialog = new PrintDialog();
    if (dialog.ShowDialog() == true)
    { 
        dialog.PrintVisual(sp, "Print job"); 
    }
}
Run Code Online (Sandbox Code Playgroud)

但上面给出了以下错误:

指定的元素已经是另一个元素的逻辑子元素.首先断开它.

有没有一种简单的方法来克隆FrameworkElement,以便我可以操作副本,打印它,然后忘记它,让XAML中的原始元素显示在屏幕上完好无损?

我想象的是这样的东西:

FrameworkElement fwe2 = FrameworkElement.Clone(fwe); //pseudo-code
Run Code Online (Sandbox Code Playgroud)

reS*_*Ned 8

我在当前项目中遇到了类似的问题,并使用此代码解决了这个问题.

public static class ExtensionMethods
{
    public static T XamlClone<T>(this T original)
        where T : class
    {
        if (original == null)
            return null;

        object clone;
        using (var stream = new MemoryStream())
        {
            XamlWriter.Save(original, stream);
            stream.Seek(0, SeekOrigin.Begin);
            clone = XamlReader.Load(stream);
        }

        if (clone is T)
            return (T)clone;
        else
            return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样它只是作为WPF项目中所有对象的方法出现,您不需要为该方法提供任何参数,并且它返回与原始对象类相同的对象.

  • 这种方法存在局限性.请参阅http://msdn.microsoft.com/en-us/library/ms754193.aspx. (5认同)

Anv*_*aka -1

我确信应该有一种简单的方法来进行复制(除了与父级分离、打印并附回之外)。例如,您可以尝试XamlWriter编写 xaml,然后通过XamlReader读回它。但我怀疑这种方式可能存在一些绑定和布局错误。

相反,我会尝试使用WriteableBitmap 拍摄可打印区域的快照并打印它。通过这种方式,您可以创建光栅和松散矢量,但我在打印方面还不够好,无法判断它是好是坏。无论如何,你可以尝试检查一下:)。

干杯,安瓦卡。