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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With