You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7下WPF UI缩放适配打印时OxyPlot空白无法打印

OxyPlot在.NET 7 WPF中打印空白问题修复方案

复现步骤

  • 克隆仓库:https://github.com/supershopping/OxyPlotPrintTest
  • 运行应用程序
  • 点击“Add Data”按钮
  • 点击“Print”按钮,选择打印机并打印在letter尺寸纸张上

平台与版本

  • 平台:WPF
  • .NET版本:.NET 7

预期行为

目标是打印WPF UI中的ReportGrid或主窗口,打印代码用于将UI缩放适配到单张letter纸张,OxyPlot应随UI缩放并正常打印。

实际行为

打印后UI右侧的按钮正常显示,但OxyPlot区域为空白。相同打印代码在.NET Framework 4.8环境下可正常工作,推测是OxyPlot与.NET 7的兼容性问题,寻求修复方案或替代方法。

相关代码

XAML代码

<Window x:Class="OxyPlotPrintTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:OxyPlotPrintTest"
    xmlns:oxy="http://oxyplot.org/wpf"
    Title="MainWindow" Height="800" Width="1280"
    Name="Main">

<Grid Name="ReportGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <oxy:PlotView x:Name="plot"/>

    <StackPanel Grid.Column="1">
        <Button  Content="Add Data" Click="Button_Click_1" Height="150"/>
        <Button Content="Print" Click="Button_Click" Height="150"/>
    </StackPanel>

</Grid>
</Window>

C#代码

public partial class MainWindow : Window
{
    public PlotModel MyModel { get; private set; }

    public MainWindow()
    {
        MyModel = new PlotModel { Title = "Example 1" };
        MyModel.Series.Add(new FunctionSeries(Math.Cos, 0, 10, 0.1, "cos(x)"));
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Visual visual = ReportGrid as Visual;
        Print(visual);
    }

    private void Print(Visual v)
    {
        System.Windows.FrameworkElement e = v as System.Windows.FrameworkElement;

        if (e == null)
            return;

        PrintDialog pd = new PrintDialog();
        pd.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
        if (pd.ShowDialog() == true)
        {
            // 保存原始缩放比例
            Transform originalScale = e.LayoutTransform;
            // 获取所选打印机的功能参数
            System.Printing.PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);

            // 计算打印相对于WPF视觉元素的缩放比例
            double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / e.ActualWidth, capabilities.PageImageableArea.ExtentHeight /
                           e.ActualHeight);

            // 应用缩放变换到视觉元素
            e.LayoutTransform = new ScaleTransform(scale, scale);

            // 获取打印机页面尺寸
            System.Windows.Size sz = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);

            // 更新视觉元素布局以匹配打印机页面尺寸
            e.Measure(sz);
            e.Arrange(new System.Windows.Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));

            // 打印视觉元素以适配单页
            pd.PrintVisual(v, "My Print");

            // 恢复原始变换
            e.LayoutTransform = originalScale;
        }
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        plot.Model = MyModel;
    }
}

问题截图

打印后OxyPlot空白截图

修复方案

1. 强制OxyPlot打印前重绘

在调用pd.PrintVisual前,强制PlotView或PlotModel重绘,确保内容已渲染:

// 在pd.PrintVisual(v, "My Print");之前添加
plot.InvalidateVisual();
// 或者
plot.Model.InvalidatePlot(true);

2. 使用OxyPlot原生打印API

绕过WPF的PrintVisual,直接调用OxyPlot提供的打印方法,避免兼容性问题:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var printDialog = new PrintDialog();
    printDialog.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
    if (printDialog.ShowDialog() == true)
    {
        // 直接打印PlotModel
        plot.Model.Print(printDialog.PrintQueue, printDialog.PrintTicket);
    }
}

3. 调整布局更新逻辑

应用缩放变换后,强制更新布局并等待渲染完成:

// 在e.Arrange之后添加
e.UpdateLayout();
// 临时等待渲染(仅作为应急方案)
System.Threading.Thread.Sleep(100);

4. 升级OxyPlot版本

检查当前OxyPlot版本,升级到最新稳定版(如2.1.0及以上),新版本已修复部分.NET 7兼容性问题。

内容的提问来源于stack exchange,提问作者Owen Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:53:20