Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
275 views
in Technique[技术] by (71.8m points)

c# - Is there an easy/built-in way to get an exact copy (clone) of a XAML element?

I need to make areas of XAML printable and so have make this button handler:

private void Button_Click_Print(object sender, RoutedEventArgs e)
{
    Customer.PrintReport(PrintableArea);
}

And in PrintReport I pack the frameworkelement into other elements in order to print it in a slightly different way than it is on the screen, like this:

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"); 
    }
}

But the above gives me the following error:

Specified element is already the logical child of another element. Disconnect it first.

Is there an easy way to clone the FrameworkElement so that I can manipulate the copy, print it, and then forget about it, leaving the original element in the XAML being displayed on the screen intact?

Something like this I would imagine:

FrameworkElement fwe2 = FrameworkElement.Clone(fwe); //pseudo-code
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I had a similar problem in my current project and solved it with this code.

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;
    }
}

This way it simply appears as a method on all objects in your WPF project, you do not need to give any parameters to the method, and it returns an object of the same class as the original.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...