风格不适用于无头wpf控制

时间:2015-04-28 20:01:11

标签: c# .net wpf wpf-controls

目标

我有一个带有嵌套ItemsControls的WPF窗口。我需要将项目提取到位图中,但不实际显示窗口。到目前为止,我已经解决了渲染可视树而不显示实际窗口的一些障碍。

问题

我的问题是输出没有应用它的样式。

我尝试过的事情

  • 如果我首先显示窗口,然后获取位图,然后关闭窗口一切看起来都很好(样式都应用了)。虽然,我不认为这种“黑客”是可以接受的,但更多的是一种故障排除方式。
  • ContentPresenter包裹在ViewBox并执行.Measure().Arrange(),但这没有帮助

我已经引用了these questions来让我更接近正确的事情,但唉,这些风格仍未应用。我假设我错过了某种强制应用样式的步骤。任何帮助,将不胜感激。仅供参考,我在VS 2012中使用.Net 4。

如果此代码的位不完全匹配,请道歉。如上所述,有一堆嵌套的ItemsControls,为了简洁起见,我试图减少所有内容,以便更容易理解。

设置控件

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);
}

上面提到的GenerateContainers功能

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);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

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.