本人做一小项目,需要自己写打印驱动,对于打印datagridview的内容,基本已经做完,现在有一点点小问题想求教。
先描述下我做的东西,自己做了个窗体来实现灵活设置,用户可以自定义打印行、列,自定义列头、单元格的字体、颜色,自定义表格线条颜色等等,如下
在单元格打印的时候,我会自动去计算每行的行高,因为如果有单元格的内容很长时,可能涉及到换行,我的做法是用循环每行(包括列头)的每个元素,用TextRenderer.MeasureText()或者Graphics.MeasureString()(网友说前者准确性高一些)去按设置的字体计算当前string的宽度,与当前列的宽度比较,如果小,就用string宽度除以列宽度,取不小于结果的最小整数来乘以按当前字体计算的行高作为当前单元格行高,每一行都取最大行高作为该行行高。代码如下:
1 double strWidth = TextRenderer.MeasureText(dgvc.Value.ToString(), dgvCellFont).Width;//e.Graphics.MeasureString(dgvc.Value.ToString(), dgvCellFont).Width; 该行去计算单元格内容的宽度 2 if (strWidth > (int)columnWidths[j]) // 与之前计算的列宽比较 3 { 4 int step = (int)Math.Ceiling(strWidth / (int)columnWidths[j]; // 这里是如果大于列宽,就相除 5 tmpRowHeightEx = (int)(Math.Ceiling(e.Graphics.MeasureString(dgvc.Value.ToString(), dgvCellFont).Height + 10) * step); //计算新行高 ,+10是一个修正,我想单元格的高度应该比文字高度高一些 6 }
这样去遍历每行计算新行高。
如果用户选择的字体比较小,类似二号、三号、四号字体这些,都没问题,但是如果用户选择更大的,比如36号字体的时候,问题就出来了,最后一列,如下图
这里首先声明下,用StringFormat去DrawString的,StringFormat几个属性设置如下:
1 StringFormat strFormat = new StringFormat(); 2 strFormat.Alignment = StringAlignment.Center; 3 strFormat.LineAlignment = StringAlignment.Center; 4 strFormat.Trimming = StringTrimming.EllipsisCharacter;
最好一行,还是设置了如果字符串超出,用省略号代替,但是我做计算行高,基本就是为了规避这个问题,想在单元格内打印出所有内容。
按道理说,计算的行高应该没问题,可是还是出现了上图的情况,我能想到,出这问题可能有2个原因
1.在方框内打印字符串时,字符串的宽度应该是小于方框的宽度,就算相等,系统也会给你换行打印的。
2.我的计算方法应该是对于字符串不复杂,都是英文数字或者字母的时候才适用。
如果单个字符的宽度越接近1/3、1/2单元格宽度,越大,越容易出这种问题。
然后我的问题是,有没有达人碰到过类似的问题,怎么解决的,有没有更合理去计算这个行高的办法?
谢谢!
如果是打印的话,在计算字符宽度的时候,是要把DC从屏幕转换为打印机然后再计算吧。
能详细点么,我这个是直接在纸张上去绘制的,计算都是直接计算纸张上这些东西的宽度和高度,最后看的结果也是在预览窗口看到的。
谢谢!
@David丶Beckham: 你可以看下MeasureText多个重载版本,希望下面两篇文章对你有帮助:
图片不能显示,麻烦上传一下图片
现在看看呢,我重新找了个网站上传了图片,不知道本论坛能否直接上传图片
@David丶Beckham: 在提问页面编辑器上方有“上传图片”的链接