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

能否在WPF控件中显示System.Drawing.Graphics对象实现打印预览?

在WPF用户控件中复用PrintDocument的Graphics逻辑实现打印预览

直接在WPF用户控件里显示System.Drawing.Graphics对象是不可行的——WPF基于DirectX的绘图系统和System.Drawing(GDI+)属于两套独立的渲染框架,无法直接兼容。但你可以通过将GDI+绘图内容渲染到Bitmap,再转换为WPF支持的ImageSource的方式,完全复用现有打印逻辑实现预览。

具体实现步骤

1. 封装可复用的绘图逻辑

先把PrintPage事件中的绘图代码抽成独立方法,避免重复编写:

// 封装原打印逻辑,接收Graphics对象作为参数
private void DrawReceiptContent(Graphics graphics)
{
    // 以下是你的原有打印代码,直接复用即可
    graphics.Clear(Color.White);
    graphics.DrawString("POS交易收据", new Font("微软雅黑", 14, FontStyle.Bold), Brushes.Black, 10, 10);
    graphics.DrawLine(Pens.DarkGray, 10, 35, 297, 35); // 80mm宽收据换算为像素(96DPI下≈307px)
    graphics.DrawString("交易时间:2024-05-20 14:30", new Font("微软雅黑", 10), Brushes.Black, 10, 45);
    graphics.DrawString("商品:矿泉水 x1  ¥3.00", new Font("微软雅黑", 10), Brushes.Black, 10, 70);
    // ...其他收据内容绘制
}

2. 生成预览用的ImageSource

创建一个Bitmap,用它的Graphics对象调用封装好的绘图方法,再将Bitmap转换为WPF可识别的ImageSource:

private ImageSource GenerateReceiptPreview()
{
    // 模拟收据尺寸:80mm宽≈307px(96DPI),高度设为足够容纳内容的值
    int receiptWidth = 307;
    int receiptHeight = 600;

    using (Bitmap previewBitmap = new Bitmap(receiptWidth, receiptHeight))
    using (Graphics graphics = Graphics.FromImage(previewBitmap))
    {
        // 调用复用的绘图逻辑
        DrawReceiptContent(graphics);

        // 将Bitmap转换为WPF的BitmapImage
        using (MemoryStream ms = new MemoryStream())
        {
            previewBitmap.Save(ms, ImageFormat.Png);
            ms.Position = 0;

            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = ms;
            bitmapImage.EndInit();
            bitmapImage.Freeze(); // 冻结对象,允许在UI线程安全使用

            return bitmapImage;
        }
    }
}

3. 在WPF用户控件中显示预览

在用户控件里添加一个Image控件,通过按钮点击或控件加载事件赋值:

// 预览按钮点击事件
private void PreviewBtn_Click(object sender, RoutedEventArgs e)
{
    ReceiptPreviewImage.Source = GenerateReceiptPreview();
}

对应的XAML片段:

<Image x:Name="ReceiptPreviewImage" Stretch="Uniform" Margin="10"/>
<Button Content="预览收据" Click="PreviewBtn_Click" Margin="10"/>

注意事项

  • DPI适配:System.Drawing默认使用96DPI,若WPF系统DPI不同,可通过graphics.DpiX = 96; graphics.DpiY = 96;强制对齐,避免预览和打印尺寸偏差。
  • 内存管理:所有实现IDisposable的对象(Bitmap、Graphics、MemoryStream)必须用using包裹,防止内存泄漏。
  • 动态高度:若收据内容长度不固定,可先计算内容所需高度(比如通过Graphics.MeasureString估算文本高度),再创建对应尺寸的Bitmap,避免内容截断或空白过多。

内容的提问来源于stack exchange,提问作者Thanuja Dilhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:15:47