Как получить скриншот всей структуры дерева TreeView? Делал это следующим кодом, но он получает изображение только видимой области дерева:
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)TreeElement.ActualWidth, (int)TreeElement.ActualHeight, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(TreeElement);
JpegBitmapEncoder jpegBitmapEncoder = new JpegBitmapEncoder
{
QualityLevel = 100
};
jpegBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (FileStream fileStream = new FileStream("Tree.jpg", FileMode.Create))
{
jpegBitmapEncoder.Save(fileStream);
fileStream.Close();
}
Проблема вот в чём.
Вы получаете правильный скриншот: ваш TreeView
именно так и выглядит. У него внутри есть ScrollViewer
, который и ограничивает видимость.
Есть несколько путей решения проблемы. Самый простой, вероятно — просмотреть дочерние элементы нашего TreeView
и найти «внутреннюю часть» ScrollViewer
'а.
Это делается так:
IEnumerable<FrameworkElement> GetChildren(FrameworkElement fe)
{
int nChildren = VisualTreeHelper.GetChildrenCount(fe);
for (int i = 0; i < nChildren; i++)
yield return (FrameworkElement)VisualTreeHelper.GetChild(fe, i);
}
IEnumerable<FrameworkElement> GetAllChildren(FrameworkElement fe) =>
new[] { fe }.Concat(GetChildren(fe).SelectMany(GetAllChildren));
Или, если вы работаете с новой .NET 4.7.1, то
IEnumerable<FrameworkElement> GetAllChildren(FrameworkElement fe) =>
GetChildren(fe).SelectMany(GetAllChildren).Prepend(fe);
Подсмотрев в визуальное дерево при помощи Live Visual Tree, видим, что нам нужен дочерний элемент типа ScrollContentPresenter
.
Пишем:
var presenter = GetAllChildren(TreeElement).OfType<ScrollContentPresenter>().First();
var content = (FrameworkElement)VisualTreeHelper.GetChild(presenter, 0);
RenderTargetBitmap renderTargetBitmap =
new RenderTargetBitmap((int)content .ActualWidth,
(int)content .ActualHeight,
96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(content);
JpegBitmapEncoder jpegBitmapEncoder = new JpegBitmapEncoder { QualityLevel = 100 };
jpegBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (var fileStream = File.Create("Tree.jpg"))
jpegBitmapEncoder.Save(fileStream);
Недостаток: вы не получаете цвет фона, т. к. фон рисуется выше по визуальному дереву. Но «подложить» фон на картинку вы уж сможете сами, хорошо?
Есть json, для которого Visual Studio сгенерировал вот такой класс
Мне нужно из C# отправить сделать то, что делается через CURL таким образом: