样式不适用于无头 wpf 控件
Styles not applying to headless wpf control
目标
我有一个带有一些嵌套 ItemsControls
的 WPF window。我需要将项目提取到位图中但实际上不显示 window。到目前为止,我已经克服了在不显示实际 window 的情况下渲染可视化树的一些障碍。
问题
我的问题是输出没有应用样式。
我试过的东西
- 如果我先显示 window,然后获取位图,然后关闭 window,一切看起来都很好(所有样式都已应用)。虽然,我不认为这个 "hack" 是可以接受的,但更像是一种故障排除形式。
- 将
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);
}
}
}
您可能需要在渲染前再次测量和排列新控件:
var groupControl = ...;
groupControl.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
groupControl.Arrange(new Rect(groupControl.DesiredSize));
这是记忆中的,我会仔细检查自己并在需要时更新。
目标
我有一个带有一些嵌套 ItemsControls
的 WPF window。我需要将项目提取到位图中但实际上不显示 window。到目前为止,我已经克服了在不显示实际 window 的情况下渲染可视化树的一些障碍。
问题
我的问题是输出没有应用样式。
我试过的东西
- 如果我先显示 window,然后获取位图,然后关闭 window,一切看起来都很好(所有样式都已应用)。虽然,我不认为这个 "hack" 是可以接受的,但更像是一种故障排除形式。
- 将
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);
}
}
}
您可能需要在渲染前再次测量和排列新控件:
var groupControl = ...;
groupControl.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
groupControl.Arrange(new Rect(groupControl.DesiredSize));
这是记忆中的,我会仔细检查自己并在需要时更新。