首页 > 解决方案 > 在屏幕前重新缩放 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;
        //}

    }

标签: c#wpf

解决方案


这就是我最终如何做到的。我最终订阅了 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();
        }
    }

    

推荐阅读