在C#中打印DataGridView时如何计算单元格高度[有长文本] [英] How to calculate cell height [that has long text] when printing DataGridView in C#
问题描述
当单元格有长文本时,我搜索但没有找到如何在打印DataGridView
时设置单元格高度
.
我没有找到一个专注于如何计算长文本高度的结果.而且我不想使用以正确的单元格高度打印它的第 3 方 DLL 文件.
我使用此代码来计算高度,但文本总是被剪切,短文本的单元格高度低于 DGV.
var tallestHeight = 0;foreach(GridRow.Cells 中的 DataGridViewCell 单元格){if (!cell.Visible) { 继续;}var s = e.Graphics.MeasureString(cell.FormattedValue.ToString(), dataGridView1.Font);var tempHeight = (int)(s.Height * Math.Ceiling(s.Width/dataGridView1.Columns[cell.ColumnIndex].Width));如果(临时高度 > 最高高度){最高高度 = 临时高度;}最高高度 = (最高高度 <22) ?22:最高高度;}iCellHeight = 最高高度;
我希望当我将 DataGridView 打印到打印机时,可以在不剪切的情况下显示所有单元格中的所有文本.长文本增加行高,如果没有长文本行高保持不变.
我的行高 = 22
我的 DataGridView 的Text wrap
是 enabled
编辑 1:
这是我的
打印预览
黄色突出显示的文本不完整全文是First Middle lastname-some text-0130011511478- تجربةة 7427/01300/8346584584563846
下面的文字完成.
如何完整显示第一行?
除了网格设置之外,您还需要使用输出大小来计算每行的足够高度以适合其内容.此外,调用采用
I searched but didn't find how to set the cell height
when printing DataGridView
when the cell has long text.
I didn't find one result that concentrate how to calculate the height with long text. And I don't want to use 3rd party DLL file that print it with right cell height.
I use this code to calculate the height but text always cut and short text has lower cell height that on DGV.
var tallestHeight = 0;
foreach (DataGridViewCell cell in GridRow.Cells)
{
if (!cell.Visible) { continue; }
var s = e.Graphics.MeasureString(cell.FormattedValue.ToString(), dataGridView1.Font);
var tempHeight = (int)(s.Height * Math.Ceiling(s.Width / dataGridView1.Columns[cell.ColumnIndex].Width));
if (tempHeight > tallestHeight)
{
tallestHeight = tempHeight;
}
tallestHeight = (tallestHeight < 22) ? 22 : tallestHeight;
}
iCellHeight = tallestHeight;
I want when I print DataGridView to printer to show all the text in all cells without cutting. Long text increase the row height and if no long text row's height stays unchanged.
I have row height = 22
Text wrap
for my DataGridView is enabled
Edit1:
Here is my DataGridView properties
Here is how i print my DataGridView: PrintDGV Class that i use
My DGV appears
Print preview
Yellow highlighted text isn't complete Full text is First Middle lastname- some text- 0130011511478- تجربةة 7427/01300/8346584584563846
The text below it complete.
How to show the first row at full?
Apart from the grid settings, you need to use the output sizes to calculate the adequate height of each row to fit their contents. Also, calling a MeasureString
method overload that takes StringFormat
is necessary to get more accurate result.
I see in the printout image above you are dividing the MarginBounds.Width
by the visible cells. Thus, the following:
Calculate
Create a method to calculate and return the proper height of each row.
// +
using System.Linq;
private int GetRowHeight(
Graphics g,
DataGridViewRow row,
Rectangle bounds,
StringFormat sf,
int minHeight = 22)
{
var cells = row.Cells.OfType<DataGridViewTextBoxCell>()
.Where(c => c.Visible);
if (cells == null) return minHeight;
var cell = cells.Aggregate((DataGridViewTextBoxCell)null, (x, y) => x != null &&
x.FormattedValue.ToString().Length > y.FormattedValue.ToString().Length ? x : y);
if (cell == null) return minHeight;
var h = g.MeasureString(cell.FormattedValue.ToString(),
row.DataGridView.Font,
new SizeF(bounds.Width / cells.Count(), bounds.Height),
sf).ToSize().Height;
return Math.Max(h + 6, minHeight); // 6 for top and bottom margins...
}
Call
Caller example and class variables to track the printing...
// +
using System.Drawing.Printing;
private int rowIndex;
private int cellCount;
private int pageNumber;
private readonly PrintDocument printDoc;
// ...
// ctor
public YourForm()
{
InitializeComponent();
printDoc = new PrintDocument();
printDoc.PrintPage += OnPrintPage;
}
// Cleanup
private void YourForm_FormClosed(object sender, FormClosedEventArgs e)
{
printDoc.Dispose();
}
// Preview
private void btnPrintPreview(object sender, EventArgs e) => Print(true);
// Print
private void btnPrint(object sender, EventArgs e) => Print();
// Print Routine
private void Print(bool preview = false)
{
rowIndex = 0;
cellCount = 0;
pageNumber = 0;
var rows = dataGridView1.Rows
.Cast<DataGridViewRow>()
.FirstOrDefault(r => !r.IsNewRow);
if (rows != null)
cellCount = rows.Cells
.OfType<DataGridViewTextBoxCell>()
.Where(c => c.Visible)
.Count();
if (cellCount == 0)
{
MessageBox.Show("Nothing to print...");
return;
}
printDoc.DefaultPageSettings.Landscape = true;
if (preview)
{
using (var pd = new PrintPreviewDialog())
{
pd.Document = printDoc;
pd.ShowDialog();
}
}
else
{
using (var pd = new PrintDialog())
{
pd.Document = printDoc;
if (pd.ShowDialog() == DialogResult.OK)
pd.Document.Print();
}
}
}
PrintDocument.PrintPage
event example.
// +
using System.Drawing.Text;
private void OnPrintPage(object sender, PrintPageEventArgs e)
{
var w = e.MarginBounds.Width / cellCount;
var x = e.MarginBounds.X;
var y = e.MarginBounds.Y;
int h;
Rectangle rec;
using (var sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
// Maybe you need to set this? I see Arabic text in the images.
// sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
// Uncomment to print the headers in the first page only.
//if (pageNumber == 0)
//{
h = dataGridView1.RowTemplate.Height;
foreach (var col in dataGridView1.Columns
.OfType<DataGridViewTextBoxColumn>()
.Where(c => c.Visible))
{
rec = new Rectangle(x, y, w, h);
e.Graphics.FillRectangle(Brushes.Gainsboro, rec);
e.Graphics.DrawString(
col.HeaderText,
col.DataGridView.Font,
Brushes.Black,
rec,
sf);
e.Graphics.DrawRectangle(Pens.Black, rec);
x += w;
}
x = e.MarginBounds.X;
y += h;
//}
for (var i = rowIndex; i < dataGridView1.RowCount; i++)
{
var row = dataGridView1.Rows[i];
if (row.IsNewRow) break;
h = GetRowHeight(e.Graphics, row, e.MarginBounds, sf);
if (h > e.MarginBounds.Height)
{
MessageBox.Show("Insufficient height.");
e.Cancel = true;
return;
}
foreach (var cell in row.Cells
.OfType<DataGridViewTextBoxCell>()
.Where(c => c.Visible))
{
rec = new Rectangle(x, y, w, h);
if (rec.Bottom > e.MarginBounds.Bottom)
{
pageNumber++;
rowIndex = i;
e.HasMorePages = true;
return;
}
e.Graphics.DrawString(
cell.FormattedValue.ToString(),
dataGridView1.Font,
Brushes.Black,
rec,
sf);
e.Graphics.DrawRectangle(Pens.Black, rec);
x += rec.Width;
}
x = e.MarginBounds.X;
y += h;
}
}
}
Output
这篇关于在C#中打印DataGridView时如何计算单元格高度[有长文本]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!