c# - 在屏幕前重新缩放 UI 元素 (WPF)
问题描述
我正在尝试为我的 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;
//}
}
解决方案
这就是我最终如何做到的。我最终订阅了 LayoutUpdated 事件来运行位图渲染。然后我取消订阅。
private void NewPrint(object sender, RoutedEventArgs e)
{
var FoundPlotView = this.FindFirstChild<PlotView>();
if (FoundPlotView != null)
{
var plotsize = new Size(700, 400);
FoundPlotView.Measure(plotsize);
FoundPlotView.Arrange(new Rect(plotsize));
}
this.LayoutUpdated += new EventHandler(Window_Loaded);
}
private void Window_Loaded(object sender, EventArgs e)
{
var printPreview = new PrintPreview();
var FoundPlotView = this.FindFirstChild<PlotView>();
if (FoundPlotView != null)
{
RenderTargetBitmap bmp = new RenderTargetBitmap(700, 400, 96, 96, PixelFormats.Pbgra32);
bmp.Render(FoundPlotView);
printPreview.ppmodel.Image1 = bmp;
}
printPreview.Show();
this.LayoutUpdated -= new EventHandler(Window_Loaded);
if (FoundPlotView != null)
{
FoundPlotView.Height = Double.NaN;
FoundPlotView.Width = Double.NaN;
(FoundPlotView.Parent as FrameworkElement).InvalidateVisual();
}
}
推荐阅读
- c# - 将 IdentityUser 关联到 EF Core 中的实体
- html - 为什么 nth-child 选择器在 css 中不起作用?
- linux - 为什么 React Native 会挂在 59% 上?
- c# - 等效于 C# 中的 C++“this”指针
- java - java合并两个List
- android - Android - 仅启用 URL 链接,但在触及 TextView 中的非 URL 链接时禁用其他链接
- bash - How to write String to a text File
- python - 使用索引列表对numpy数组的元素执行操作
- java - 读取对象类java实例的属性
- swift - 在模拟器中启用 CoreLocation