0

I have a MVVM WPF application.

I am trying to capture current content of the window without the Window Form Header and Window Form borders.

I know this is easy to do in a Windows Forms application, here is an example.

I would like to do the same in my WPF application but I am lost. I have found an example here but it captures all the screen.

How can I do this? Also, once captured I need to send it directly to print to the default printer.

So I am trying to do the following without success:

  1. Capture WPF window content without the Window Form Header and Window Form borders.
  2. Print this screen capture to default printer without showing any print dialog.

ATTEMPT #1 - ISSUE 1 - Capture screen: Regarding point 1 (capturing content of window) I have done below. SnapShotPNG solution is working perfectly.

TopGrid UI Element in GetSnapshotButton_Click is the grid from which I want to do snapshot its content.

GetJpgImage solution is not working at all. In the snapshot appears black zones. Why?

Solutions extracted from here and here.

    private void GetSnapshotButton_Click(object sender, RoutedEventArgs e)
    {
        var uri = new System.Uri("c:\\Temp\\capture1.png");            
        SnapShotPNG(TopGrid, uri, 1);

        uri = new System.Uri("c:\\Temp\\capture2.jpg");
        GetJpgImage(TopGrid, uri, 1, 100);
    }

    public void SnapShotPNG(UIElement source, Uri destination, int scale)
    {
        try
        {
            double actualHeight = source.RenderSize.Height;
            double actualWidth = source.RenderSize.Width;

            double renderHeight = actualHeight * scale;
            double renderWidth = actualWidth * scale;

            RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);
            VisualBrush sourceBrush = new VisualBrush(source);

            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext drawingContext = drawingVisual.RenderOpen();

            using (drawingContext)
            {
                drawingContext.PushTransform(new ScaleTransform(scale, scale));
                drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
            }
            renderTarget.Render(drawingVisual);

            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(renderTarget));
            using (FileStream stream = new FileStream(destination.LocalPath, FileMode.Create, FileAccess.Write))
            {
                encoder.Save(stream);
            }
        }
        catch (Exception e)
        {
            //MessageBox.Show(e);
        }
    }

    ///
    /// Gets a JPG "screenshot" of the current UIElement
    ///
    /// UIElement to screenshot
    /// Scale to render the screenshot
    /// JPG Quality
    /// Byte array of JPG data
    public void GetJpgImage(UIElement source, Uri destination, double scale, int quality)
    {
        double actualHeight = source.RenderSize.Height;
        double actualWidth = source.RenderSize.Width;

        double renderHeight = actualHeight * scale;
        double renderWidth = actualWidth * scale;

        RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);
        VisualBrush sourceBrush = new VisualBrush(source);

        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();

        using (drawingContext)
        {
            drawingContext.PushTransform(new ScaleTransform(scale, scale));
            drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
        }
        renderTarget.Render(drawingVisual);

        JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
        jpgEncoder.QualityLevel = quality;
        jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

        using (FileStream stream = new FileStream(destination.LocalPath, FileMode.Create, FileAccess.Write))
        {
            jpgEncoder.Save(stream);
        }
    }

ATTEMPT #2 - ISSUE 1 - Capture screen: Using Dymanoid solution works but with one problem: Content does not fit in one page. I am trying now to fit into one page. To fit content into one page I am trying to do what is explained here.

for printing grid cotent (see here):

PrintDialog printDlg = new PrintDialog();
printDlg.PrintVisual(TopGrid, "Grid Printing.");

for printing entire wpf window (see here):

PrintDialog printDlg = new PrintDialog();
printDlg.PrintVisual(this, "Window Printing.");
Willy
  • 9,848
  • 22
  • 141
  • 284
  • 1
    Use the `PrintDialog.PrintVisual` method. Provide your root visual element in the `Window` (e.g. `Grid` or whatever you have) to that method. – dymanoid Nov 06 '17 at 16:06
  • @dymanoid could you provide a little example? Your suggestion is about to solve point 2 in my post? This method you say prints the snapshot to printer, right? it does not take a snapshot. – Willy Nov 06 '17 at 17:41
  • @dymanoid ok, i have done, it automatically takes a snapshot and then prints to default printer. What happens is that content is not being fit in one page. – Willy Nov 06 '17 at 18:01

0 Answers0