【发布时间】:2020-07-27 08:57:51
【问题描述】:
我正在尝试为我的 WPF 应用程序实现 PrintPreview。而且我在调整元素大小和重绘元素时遇到问题。我有一个绘图(OxyPlot),无论窗口大小如何,我都希望打印页面保持固定大小(700x400)。所以我让 NewPrint() 找到元素,调整它的大小,然后为打印页面渲染位图。
它有效,但仅在第二次之后,我认为这是因为 UI 元素在窗口呈现之前不会更新。第一次(左图),如果我进行打印预览,它不会调整大小。但第二次(右图)它会正确调整大小。
我尝试过 UpdateLayout(),但由于某种原因,这会使位图变为空白。然后我考虑了 OnRender() 但担心它会低效地消耗资源。如何在渲染位图之前更新布局?
这种方法是我的尝试,但有人能给我一些关于如何将元素调整为固定大小然后渲染图像的指导吗?
private void NewPrint(object sender, RoutedEventArgs e)
{
PrintPreview printPreview = new PrintPreview();
var FoundPlotView = this.FindFirstChild<PlotView>();
if (FoundPlotView != null)
{
var plotsize = new Size(700, 400);
FoundPlotView.Measure(plotsize);
FoundPlotView.Arrange(new Rect(plotsize));
//FoundPlotView.UpdateLayout();
//FoundPlotView.InvalidateArrange();
//FoundPlotView.InvalidateMeasure();
//(FoundPlotView.Parent as FrameworkElement).UpdateLayout();
FoundPlotView.InvalidatePlot(true);
}
RenderTargetBitmap bmp = new RenderTargetBitmap(700, 400, 96, 96, PixelFormats.Pbgra32);
bmp.Render(FoundPlotView);
printPreview.ppmodel.Image1 = bmp;
printPreview.Show();
//if (FoundPlotView != null)
//{
// FoundPlotView.Height = Double.NaN;
// FoundPlotView.Width = Double.NaN;
//}
//if (FoundPlotView2 != null)
//{
// FoundPlotView2.Height = Double.NaN;
// FoundPlotView2.Width = Double.NaN;
//}
}
【问题讨论】:
-
在Measure and Arrange之后你也试过
InvalidateVisual()吗?请注意,您应该遵守命名约定并将变量命名为foundPlotView。此外,如果您使用var,请尽可能使用它,即var printPreview和var bmp。 -
不确定 OxPlot 是否可能异步渲染,但您也可以尝试声明事件处理程序
async并在bmp.Render之前以合理的延迟时间调用await Task.Delay()。 -
请注意,从可视化树中重新排列现有的 PlotView 元素似乎很奇怪。考虑创建一个显示相同数据的新数据。
-
@Clemens 是的,我也尝试过 InvalidateVisual,但结果相同。并感谢您的提示!是的,这很奇怪......我重新排列了 PlotView 元素,但我必须撤消该更改(代码末尾为 Double.NaN)以将元素的大小重置为 Auto。