2016-02-10 6 views
1

Я искал и искал, но не смог найти что-либо с той же проблемой, что и я. Я пытаюсь сделать несколько скриншотов с высоким разрешением/dpi приложения WPF. Единственная проблема заключается в том, что мне нужно включать информацию из всплывающих подсказок диаграммы в рендеринге, кроме того, что я могу скрыть скриншоты просто отлично.WPF Включая подсказку в Render с RenderTargetBitmap

В настоящее время я использую Infragistics XamDataChart, и я генерирую всплывающие подсказки в коде, а не в xaml.

Кто-нибудь знает, как получить всплывающую подсказку в визуальном дереве, чтобы он отображал? Или иметь возможность отображать все окно и все внутри него, включая наложения всплывающих подсказок?

Код для визуализации:

public static void RenderVisualToFile(this FrameworkElement visual) 
    { 
     var width = (int)visual.RenderSize.Width; 
     var height = (int)visual.RenderSize.Height; 

     RenderTargetBitmap renderTarget = new RenderTargetBitmap(width * 4, height * 4, 384, 384, PixelFormats.Pbgra32); 
     renderTarget.Render(visual); 

     // Encode and save to PNG file 
     var enc = new PngBitmapEncoder(); 
     enc.Frames.Add(BitmapFrame.Create(renderTarget)); 

     if (Directory.Exists("Screenshots")) 
     { 
      using (var stm = File.Create(@"Screenshots\Render_" + DateTime.Now.ToString("yyMMMdd_HHmmss") + ".png")) 
       enc.Save(stm); 
     } 
     else 
     { 
      Directory.CreateDirectory("Screenshots"); 
      using (var stm = File.Create(@"Screenshots\Render_" + DateTime.Now.ToString("yyMMMdd_HHmmss") + ".png")) 
       enc.Save(stm); 
     } 
    }  

И я называю это в коде MainWindow позади.

if (e.Key == Key.PrintScreen) 
    { 
     this.RenderVisualToFile(); 
    } 
+0

Ever получить ответ на этот вопрос? Благодарю. –

ответ

1

Немного поздно, но, возможно, кто-то может использовать мое решение.

Моего класс Скриншота основывается на следующие решениях:

  • Создание скриншотов основаны на пост на QMINO технического блог High Res Screenshots
  • Чтобы получить Открывшиеся в настоящее время подсказок я использую фрагмент коды размещено здесь: Find all opened Popups in WPF application
  • Это мне потребовалось некоторое время, чтобы найти решение о том, как объединить UIElement для экрана с POPUPS но комментарий Clemens дал окончательный ключ Overlay Images with PngBitmapEncoder in WPF

Я использую кортежи для возврата нескольких параметров C# 7.0 Tuples.

Так вот мой класс:

using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Windows; 
using System.Windows.Controls.Primitives; 
using System.Windows.Interop; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 

public class Screenshot 
{ 
     //UIElement to create screenshot 
     private UIElement _element; 
     //Bounds for the screenshot 
     private Rect _screenshotBounds; 
     //Path for Screenshot 
     private string _path; 


     private const int DPI = 384; 
     private const double BASEDPI = 96; 
     private const double DPISCALE = DPI/BASISDPI; 

     public Screenshot(UIElement element, string path) 
     { 
      this._element = element; 
      this._screenshotBounds = this.createBounds(this._element); 
      this._path = path; 
     } 

     //public interface to create the screenshot 
     public void createScreenshot() 
     { 
     if (this._element == null) 
     { 
      return; 
     } 
     //Create a list of tuples with the elements to render in the screenshot 
     List<(UIElement, Rect, Point)> listElements = new List<(UIElement, Rect, Point)> 
     { 
       //Fist element in the list should be the actual UIElement 
       this.createElementBoundPosition(this._element); 
     }; 

     RenderTargetBitmap renderBitMap = this.createBitMap(this._screenshotBounds); 

     //Get the opened Popups, create a list of tuples for the Popups and add them to the list of elements to render 
     listElements.AddRange(this.createListPopUpBoundsPosition(this.getOpenPopups())); 

     DrawingVisual drawingVisual = this.createDrawingVisual(listElements); 
     renderBitMap.Render(drawingVisual); 

     this.saveRTBAsPNG(renderBitMap); 
     } 

     //Create DrawingVisual based on List of Tuples 
     private DrawingVisual createDrawingVisual(List<(UIElement, Rect, Point)> listElements) 
     { 
      DrawingVisual drawingVisual = new DrawingVisual(); 

      using (DrawingContext context = drawingVisual.RenderOpen()) 
      { 
       foreach((UIElement element, Rect bounds, Point position) in listElements) 
       { 
         VisualBrush visualBrush = new VisualBrush(element); 
         context.DrawRectangle(visualBrush, null, new Rect(position, bounds.Size)); 
       } 
      } 

      return drawingVisual; 
     } 

     //Save RenderTargetBitmap to file 
     private void saveRTBAsPNG(RenderTargetBitmap bitmap) 
     { 
      PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder() 
      { 
       Interlace = PngInterlaceOption.On 
      } 

      pngBitmapEncoder.Frames.Add(BitmapFrame.Create(bitmap)); 

      using (FileStream fileStream = File.Create(this._path)) 
      { 
       pngBitmapEncoder.Save(fileStream); 
      } 
     } 

     //Create Bounds for Element 
     private Rect createBounds(UIElement element) 
     { 
      new Rect(new Size((int)element.RenderSize.Width, (int)element.RenderSize.Height)); 
     } 

     //Create a Tuple with the Element, its bounds and its position 
     private (UIElement element, Rect bounds, Point position) createElementBoundPosition(UIElement element) 
     { 
      return (element, this.createBounds(element), element.PointToScreen(new Point(0,0))); 
     } 

     //create the RenderTargetBitmap 
     private RenderTargetBitmap createBitMap(Rect bounds) 
     { 
      (int width, int height) calculatedBounds = this.calculateBounds(bounds); 
      return new RenderTargetBitmap(calculatedBounds.width, calculatedBounds.height, DPI, DPI, PixelFormats.Pbgra32); 
     } 

     //recalculate bounds according to the scale 
     private (int width, int heigth) calculateBounds(Rect bounds) 
     { 
      int width = (int)(bounds.Width * DPISCALE); 
      int height = (int)(bounds.Height * DPISCALE); 
      return (width, height); 
     } 

     //Convert the list of Popups into a List of Tuples 
     private List<(UIElement element, Rect bounds, Point position)> createListPopUpBoundsPosition(List<Popup> listPopup) 
     { 
      List<(UIElement, Rect, Point)> list = new List<(UIElement, Rect, Point)>(); 

      foreach (Popup p in listPopup) 
      { 
       //The Child-Element contains the UIElement to render 
       UIElement uiElement = p.Child; 
       list.Add(this.createElementBoundPosition(uiElement)); 
      } 
      return list; 
     } 

     //get the open Popups 
     private List<Popup> getOpenPopups() 
     { 
      return PresentationSource.CurrentSources.OfType<HwndSource>() 
       .Select(h => h.RootVisual) 
       .OfType<FrameworkElement>() 
       .Select(f => f.Parent) 
       .OfType<Popup>() 
       .Where(p => p.IsOpen).ToList(); 
     } 

} 
Смежные вопросы