Goal
I have a WPF window with some nested ItemsControls
. I need to extract the items into bitmaps but without actually displaying the window. So far, I have gotten through some of the hurdles of rendering the visual tree without displaying the actual window.
Problem
My problem is that the output doesn't have the styles applied to it.
Things I've tried
ContentPresenter
in a ViewBox
and doing a .Measure()
and .Arrange()
but that didn't help I've referenced these questions to get me closer to getting things right, but alas the styles still aren't applied. I assume that I'm missing some sort of step that forces the styles to be applied. Any help would be appreciated. FYI, I'm using .Net 4 in VS 2012.
Apologies if bits of this code don't quite match up. As mentioned above there are a bunch of nested ItemsControls and for the sake of brevity I've tried to slim everything down to make it easier to follow.
Setting up the control
ucAncillary ancillaryControl = new ucAncillary(AncillaryGroups);
ancillaryControl.ApplyTemplate();
ancillaryControl.UpdateLayout();
ancillaryControl.Measure(new System.Windows.Size(Double.PositiveInfinity, Double.PositiveInfinity));
ancillaryControl.Arrange(new Rect(ancillaryControl.DesiredSize));
//AncillaryGroups is the name of the ItemsControl that I want the items from
ancillaryControl.AncillaryGroups.generateContainers();
foreach (var group in AncillaryGroups)
{
var groupControl = this.AncillaryGroups.ItemContainerGenerator.ContainerFromItem(group) as ContentPresenter;
groupControl.ApplyTemplate();
RenderTargetBitmap rtb = new RenderTargetBitmap((int)groupControl.DesiredSize.Width, (int)groupControl.DesiredSize.Height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(groupControl);
MemoryStream stream = new MemoryStream();
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
encoder.Save(stream);
type.RenderedBitmap = new Bitmap(stream);
}
The GenerateContainers function mentioned above
public static void generateContainers(this ItemsControl c)
{
IItemContainerGenerator generator = c.ItemContainerGenerator;
GeneratorPosition position = generator.GeneratorPositionFromIndex(0);
using (generator.StartAt(position, GeneratorDirection.Forward, true))
{
foreach (object o in c.Items)
{
DependencyObject dp = generator.GenerateNext();
generator.PrepareItemContainer(dp);
}
}
}
You may have to measure and arrange the new controls again before rendering:
var groupControl = ...;
groupControl.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
groupControl.Arrange(new Rect(groupControl.DesiredSize));
This is by memory, I'll double check myself and update this if needed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.