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

WPF中DocumentPaginator内图片无法显示的问题排查

WPF报表Logo图片不显示问题排查

问题描述

我在WPF中制作展示信息列表的报表,要求每页顶部带标题和Logo图片的页眉,内容超出自动分页。但预览时只能看到文本,同目录下的bmp格式Logo无法显示。我试过把图片加载逻辑移到GetPage函数外,传入BitmapImage给分页器类,还是没解决。

问题代码

public override DocumentPage GetPage(int pageNumber)
{

    //Create a test string for the purposes of measurement.
    FormattedText text = GetFormattedText("A");

    double col1_X = margin;
    double col2_X = col1_X + text.Width * 15;

    //Retreive the columns name
    string colName1 = dt.Columns[0].ColumnName;
    string colName2 = dt.Columns[1].ColumnName;

    //Calculate the range of rows that fits on this page
    int minRow = pageNumber * rowsPerPage;
    int maxRow = minRow + rowsPerPage;

    //Create the visual for the page
    DrawingVisual visual = new DrawingVisual();

    //Set the position to the top-left corner of the principal area.
    Point point = new Point(margin, margin);

    using (DrawingContext dc = visual.RenderOpen())
    {
        string Percorso = Environment.CurrentDirectory + "\\logo.bmp";
        BitmapImage bitmap = new BitmapImage(new Uri(Percorso, UriKind.Relative));
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.Freeze();

        //Draw the column header
        Typeface columnHeaderTypeface = new Typeface(typeface.FontFamily, FontStyles.Normal, FontWeights.Bold, FontStretches.Normal);
        point.X = margin;
        int contaColonne = 0;
        if (dt.Columns.Count > widths.Length)
        {
            throw new Exception("Numero di colonne diverso dal numero delle larghezze");
        }
        foreach (DataColumn datacolumn in dt.Columns)
        {
            text = GetFormattedText(datacolumn.ColumnName, columnHeaderTypeface);
            dc.DrawText(text, point);
            point.X += widths[contaColonne];
            contaColonne++;
        }

        //Draw header
        dc.DrawImage(bitmap, new Rect(100, 40, 60, 40));
        Point HeaderPoint = new Point(200, 40);
        text = GetFormattedText("Resoconto pesate", 40, columnHeaderTypeface);
        dc.DrawText(text, HeaderPoint);
        HeaderPoint.X += 450;
        HeaderPoint.Y -= 30;
        text = GetFormattedText(DateTime.Today.ToShortDateString(), columnHeaderTypeface);
        dc.DrawText(text, HeaderPoint);

        //Draw footer
        text = GetFormattedText((pageNumber + 1).ToString(), columnHeaderTypeface);
        dc.DrawText(text, new Point((pageSize.Width - text.Width) / 2, PageSize.Height - (margin / 2) + text.Height / 2));
        dc.DrawLine(new Pen(Brushes.Black, 2), new Point(margin, pageSize.Height - (margin / 2)), new Point(pageSize.Width - margin, pageSize.Height - (margin / 2)));

        //Draw the line underneath.
        dc.DrawLine(new Pen(Brushes.Black, 2), new Point(margin, margin + text.Height), new Point(pageSize.Width - margin, margin + text.Height));

        point.Y += text.Height;

        //Draw the column values.
        for (int i = minRow; i < maxRow; i++)
        {
            //Check for the end of the last (half-filled) page.
            if (i > (dt.Rows.Count - 1)) break;

            point.X = margin;
            contaColonne = 0;
            foreach (DataColumn datacolumn in dt.Columns)
            {
                text = GetFormattedText(dt.Rows[i][datacolumn.ColumnName].ToString());
                dc.DrawText(text, point);
                point.X += widths[contaColonne];
                contaColonne++;
            }
            point.Y += text.Height;

        }

        dc.Close();
    }

    return new DocumentPage(visual, pageSize, new Rect(pageSize), new Rect(pageSize));
}

问题原因及解决方案

1. 图片路径与Uri类型不匹配

你用Environment.CurrentDirectory + "\\logo.bmp"拼接绝对路径,却使用UriKind.Relative,会导致Uri解析错误。应改用绝对Uri加载:

string Percorso = Path.Combine(Environment.CurrentDirectory, "logo.bmp");
BitmapImage bitmap = new BitmapImage(new Uri(Percorso, UriKind.Absolute));

2. BitmapImage加载顺序错误

设置CacheOption = BitmapCacheOption.OnLoad的时机不对,必须在BeginInit和EndInit块内配置参数,确保加载逻辑生效:

BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(Percorso, UriKind.Absolute);
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
bitmap.Freeze();

这种方式能避免异步加载导致的图片未就绪问题。

3. 图片绘制区域被覆盖

检查dc.DrawImage(bitmap, new Rect(100, 40, 60, 40))的位置:

  • 确认该Rect未被后续绘制的列标题、文本覆盖;
  • 可临时将Logo绘制到左上角(比如new Rect(10,10,60,40))测试是否显示,排除位置问题。

4. 文件存在性与权限验证

  • 用File.Exists(Percorso)提前验证文件是否存在;
  • 确保程序有读取该文件的权限,尤其是部署后的环境。

5. 外部加载图片的正确方式

若要将图片加载移到GetPage外,需确保BitmapImage全局复用且冻结:

// 类级别全局变量
private BitmapImage _logoBitmap;

// 构造函数或初始化方法中加载
public YourPaginatorClass()
{
    string Percorso = Path.Combine(Environment.CurrentDirectory, "logo.bmp");
    _logoBitmap = new BitmapImage();
    _logoBitmap.BeginInit();
    _logoBitmap.UriSource = new Uri(Percorso, UriKind.Absolute);
    _logoBitmap.CacheOption = BitmapCacheOption.OnLoad;
    _logoBitmap.EndInit();
    _logoBitmap.Freeze(); // 冻结后支持跨线程使用,适配分页场景
}

// 在GetPage中直接使用
dc.DrawImage(_logoBitmap, new Rect(100, 40, 60, 40));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 07:54:54