.net - 创建具有多种页面大小的 XPS 文档
问题描述
我正在从 XAML 元素创建 XPS 文件。不仅如此,我正在创建 XPS 文件,其中每个页面的大小可能不同。看到这个最小的复制:
using (Package pkg = Package.Open("out.xps", FileMode.Create))
using (XpsDocument doc = new XpsDocument(pkg))
{
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
SerializerWriterCollator collator = writer.CreateVisualsCollator();
WritePage(816, 1344); // 8.5 x 14
WritePage(816, 1056); // 8.5 x 11
WritePage(816, 1344);
WritePage(816, 1056);
collator.EndBatchWrite();
doc.Close();
pkg.Close();
void WritePage(double width, double height)
{
var element = new Border()
{
Width = width,
Height = height,
BorderBrush = Brushes.Black,
BorderThickness = new Thickness(10.0)
};
Size size = new Size(width, height);
element.Measure(size);
element.Arrange(new Rect(size));
element.UpdateLayout();
collator.Write(element);
}
}
我遇到的问题是我所有的页面最终都是相同的大小。或者更准确地说,与第一页大小相同。该文档的页面均显示为:
<FixedPage ... Width="816" Height="1344">
我第一次尝试解决这个问题是PrintTicket
在我写的时候设置一个 - 但它没有效果。
稍后进行一些调试,我将问题追溯到 WPF 方法XpsSerializationManager.SaveAsXml
:
if (this._simulator == null)
{
this._simulator = new ReachHierarchySimulator(
(PackageSerializationManager) this, serializedObject);
}
...
if (this._isBatchMode)
{
xmlWriter = this._simulator.SimulateBeginFixedPage();
}
在这里,它_simulator
仅在第一次调用时进行初始化SaveAsXml
。存储在模拟器中的是serializedObject
——Visual
我们试图保存的。问题是,这个参考在后续调用中仍然存在。
接下来,它调用_simulator.SimulateBeginFixedPage
创建第一个<FixedPage>
元素——但因为它引用了原始对象,所以每个页面的大小都与该对象相同。
所以我所做的解决方法是在每次Write
调用之前通过反射更新该引用:
void WritePage(double width, double height)
{
var element = new Border()
{
Width = width,
Height = height,
BorderBrush = Brushes.Black,
BorderThickness = new Thickness(10.0),
Tag = pageCounter++
};
object manager = collator.GetType()
.GetField("_manager", BindingFlags.Instance | BindingFlags.NonPublic)
?.GetValue(collator);
object simulator = manager?.GetType()
.GetField("_simulator", BindingFlags.Instance | BindingFlags.NonPublic)
?.GetValue(manager);
simulator?.GetType()
.GetField("_serializedObject", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(simulator, element);
Size size = new Size(width, height);
element.Measure(size);
element.Arrange(new Rect(size));
element.UpdateLayout();
collator.Write(element);
}
但是——我觉得这太奇怪了,可能是我使用 WPF 的问题,而不是 WPF 本身的错误。有什么我想念的吗?
解决方案
推荐阅读
- sql - 如何从 sql 中的总行数和状态计算百分比?
- javascript - 如何使用 javascript 进行连接?
- python - 连接未知数量的掩码
- c++ - 如何对数组进行随机洗牌
- python - 我应该如何解决 Django 中这个奇怪的主键错误?
- r - 如何在ggplot2中绘制png图像?
- bash - 在 docker 中执行脚本时,产生超过 545 个任务后等待报告的“pid X 不是此 shell 的子项”错误
- html - 列表项目符号:是否可以使用 (1) 内容属性,同时 (2) 保留文本对齐方式?
- c# - 没有太多泛型参数的 C# 代码重用
- c# - 解决视图中的部分/不完整路由