¿Cómo tomar una captura de pantalla de un control WPF?

Creé una aplicación WPF usando el control WPF de Bing Maps. Me gustaría poder capturar solo el control de mapas de Bing.

Es usar este código para hacer la captura de pantalla:

// Store the size of the map control int Width = (int)MyMap.RenderSize.Width; int Height = (int)MyMap.RenderSize.Height; System.Windows.Point relativePoint = MyMap.TransformToAncestor(Application.Current.MainWindow).Transform(new System.Windows.Point(0, 0)); int X = (int)relativePoint.X; int Y = (int)relativePoint.Y; Bitmap Screenshot = new Bitmap(Width, Height); Graphics G = Graphics.FromImage(Screenshot); // snip wanted area G.CopyFromScreen(X, Y, 0, 0, new System.Drawing.Size(Width, Height), CopyPixelOperation.SourceCopy); string fileName = "C:\\myCapture.bmp"; System.IO.FileStream fs = System.IO.File.Open(fileName, System.IO.FileMode.OpenOrCreate); Screenshot.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp); fs.Close(); 

Mi problema:

El Width y la Height parecen ser malos (valores falsos). La captura de pantalla producida parece usar coordenadas incorrectas.

Mi captura de pantalla:

Mi captura de pantalla

Lo que espero

Captura de pantalla deseada

¿Por qué obtengo este resultado? Intenté en modo Release, y sin Visual Studio, el resultado es el mismo.

Una captura de pantalla es una toma de la pantalla … todo en la pantalla. Lo que desea es guardar una imagen de un solo UIElement y puede hacerlo utilizando el método RenderTargetBitmap.Render . Este método toma un parámetro de entrada Visual y afortunadamente, esa es una de las clases base para todos los UIElement s. Entonces, suponiendo que quiera guardar un archivo .png, podría hacer esto:

 RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(yourMapControl); PngBitmapEncoder pngImage = new PngBitmapEncoder(); pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); using (Stream fileStream = File.Create(filePath)) { pngImage.Save(fileStream); }