是否可以在不包装文本的情况下使用多行DataGridView单元格?

我知道我可以在RowTemplateDefaultCellStyle上将DefaultCellStyle设置为true,但这并没有给我我想要的行为。 我在每个单元格中显示一个字符串列表,因此我希望识别回车符,但我不希望长项目包装的文本。

有谁知道是否有可能实现这一目标?

我希望这就是你要找的东西: 屏幕截图

我用过两个事件:

  1. 我在细胞编辑后测量了身高。
  2. 我在绘制细胞时测量了文本,并在需要时修剪它,并重复直到它适合。

码:

 public partial class Form1 : Form { private readonly int _rowMargins; public Form1() { InitializeComponent(); int rowHeight = dataGridView1.Rows[0].Height; _rowMargins = rowHeight - dataGridView1.Font.Height; } private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) { DataGridView view = sender as DataGridView; DataGridViewCell cell = view.Rows[e.RowIndex].Cells[e.ColumnIndex]; string text = string.Format("{0}", cell.FormattedValue); if (!string.IsNullOrEmpty(text)) { Size size = TextRenderer.MeasureText(text, view.Font); view.Rows[e.RowIndex].Height = Math.Max(size.Height + _rowMargins, view.Rows[e.RowIndex].Height); } } private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) { if (e.ColumnIndex == -1 || e.RowIndex == -1) { return; } e.Paint(e.ClipBounds, DataGridViewPaintParts.All ^ DataGridViewPaintParts.ContentForeground); DataGridView view = sender as DataGridView; string textToDisplay = TrimTextToFit(string.Format("{0}", e.FormattedValue), (int) (e.CellBounds.Width * 0.96), view.Font); bool selected = view.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; SolidBrush brush = new SolidBrush(selected ? e.CellStyle.SelectionForeColor : e.CellStyle.ForeColor); e.Graphics.DrawString(textToDisplay, view.Font, brush, e.CellBounds.X, e.CellBounds.Y + _rowMargins / 2); e.Handled = true; } private static string TrimTextToFit(string text, int contentWidth, Font font) { Size size = TextRenderer.MeasureText(text, font); if (size.Width < contentWidth) { return text; } int i = 0; StringBuilder sb = new StringBuilder(); while (i < text.Length) { sb.Append(text[i++]); size = TextRenderer.MeasureText(sb.ToString(), font); if (size.Width <= contentWidth) continue; sb.Append("..."); while (sb.Length > 3 && size.Width > contentWidth) { sb.Remove(sb.Length - 4, 1); size = TextRenderer.MeasureText(sb.ToString(), font); } while (i < text.Length && text[i] != Environment.NewLine[0]) { i++; } } return sb.ToString(); } } 

请享用,
奥菲尔

设计师代码:

 partial class Form1 { ///  /// Required designer variable. ///  private System.ComponentModel.IContainer components = null; ///  /// Clean up any resources being used. ///  /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code ///  /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///  private void InitializeComponent() { this.dataGridView1 = new System.Windows.Forms.DataGridView(); this.LineNumber = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Content = new System.Windows.Forms.DataGridViewTextBoxColumn(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); this.SuspendLayout(); // // dataGridView1 // this.dataGridView1.AllowUserToDeleteRows = false; this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.LineNumber, this.Content}); this.dataGridView1.Location = new System.Drawing.Point(13, 13); this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.RowHeadersWidth = 55; this.dataGridView1.RowTemplate.DefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.False; this.dataGridView1.Size = new System.Drawing.Size(493, 237); this.dataGridView1.TabIndex = 0; this.dataGridView1.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEndEdit); this.dataGridView1.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(this.dataGridView1_CellPainting); // // LineNumber // this.LineNumber.FillWeight = 30F; this.LineNumber.Frozen = true; this.LineNumber.HeaderText = "#"; this.LineNumber.MaxInputLength = 3; this.LineNumber.Name = "LineNumber"; this.LineNumber.ReadOnly = true; this.LineNumber.Resizable = System.Windows.Forms.DataGridViewTriState.False; this.LineNumber.Width = 30; // // Content // this.Content.HeaderText = "Content"; this.Content.Name = "Content"; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(518, 262); this.Controls.Add(this.dataGridView1); this.Name = "Form1"; this.Text = "Is it possible to have Multi-line DataGridView cells without wrapping text?"; ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.DataGridView dataGridView1; private System.Windows.Forms.DataGridViewTextBoxColumn LineNumber; private System.Windows.Forms.DataGridViewTextBoxColumn Content; } 

我测试这段代码,结果非常好,请测试一下:

注意:创建表单和Datagrid,设置以下datagrid属性

1- AutoSizeRowsMo​​de到AllCells。
2-目标列的WrapMode为True

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace DGMultiLine { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { int max = 12; //min Column Width in Char //do this for all rows of column for max Line Size in values string str = "Hello\r\nI am mojtaba\r\ni like programming very very \r\nrun this code and pay attention to result\r\n Datagrid Must show this Line Good are you see whole of this Thats Finished!"; string[] ss = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); //find max Line Size To Now for (int i = 0; i < ss.Length; i++) if (ss[i] != null && ss[i] != "") if (ss[i].Length > max) max = ss[i].Length; //Set target Column Width dataGridView1.Columns[0].Width = max*5;//for adequate value you must refer to screen resolution //filling datagrigView for all values dataGridView1.Rows[0].Cells[0].Value = str; } } } 

你可以通过真正的fullText和一个可见的列添加一个隐藏的列,它通过上面的代码显示字符串值,但是字符串行的大小超过了你的Max Column Size剪辑字符串,并添加…到结尾。 (如果不清楚请写完整代码)

通过与字符串一起进行\ r \ n,它对我有用。

例如“Hello”+ \ r \ n。 然后它进入下一行。

编辑:

刚刚看到这是WinForms。 上面的技巧只适用于WPF。

EDIT2:

您可以使用:

 dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True; 

如果你不想要长项包装,你只需:

 String stringTest = "1234567891"; if (stringTest.Length > 8) { stringTest = stringTest.Replace(stringTest.Substring(8), "..."); } 

如果String长于8,则会添加“…”。

一种方法是你可以只显示一些单词,然后可以在鼠标hover在该单元格上的工具提示中显示全文。

如果不将WrapMode设置为true,我还没有找到方法。 但是,您应该能够通过将单元格的宽度设置为足够宽以在一行上显示所有项目来“欺骗”DataGridView。

以下是使用ComboBo完成此操作的示例。

此类获取DataGridView实例并添加用于修剪宽度和高度的多线椭圆(…)的行为。

用法:

 MultilineTriming.Init(ref dataGridView); // that's it! 

请享用,

 public static class MultilineTriming { private static int _rowMargins; public static void Init(ref DataGridView dataGridView) { dataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; dataGridView.DefaultCellStyle.WrapMode = DataGridViewTriState.False; _rowMargins = dataGridView.RowTemplate.Height - dataGridView.Font.Height; Unregister(dataGridView); dataGridView.CellEndEdit += DataGridViewOnCellEndEdit; dataGridView.CellPainting += DataGridViewOnCellPainting; dataGridView.RowsAdded += DataGridViewOnRowsAdded; dataGridView.Disposed += DataGridViewOnDisposed; } private static void DataGridViewOnRowsAdded(object sender, DataGridViewRowsAddedEventArgs e) { DataGridView view = sender as DataGridView; DataGridViewRow row = view.Rows[e.RowIndex]; foreach (DataGridViewCell cell in row.Cells) { if (cell.FormattedValue == null) { continue; } Size size = TextRenderer.MeasureText((string)cell.FormattedValue, view.Font); row.Height = Math.Max(size.Height + _rowMargins, row.Height); } } private static void DataGridViewOnDisposed(object sender, EventArgs eventArgs) { DataGridView dataGridView = sender as DataGridView; Unregister(dataGridView); } public static void Unregister(DataGridView dataGridView) { dataGridView.RowsAdded -= DataGridViewOnRowsAdded; dataGridView.CellEndEdit -= DataGridViewOnCellEndEdit; dataGridView.CellPainting -= DataGridViewOnCellPainting; } private static void DataGridViewOnCellEndEdit(object sender, DataGridViewCellEventArgs e) { DataGridView view = sender as DataGridView; DataGridViewRow row = view.Rows[e.RowIndex]; DataGridViewCell cell = row.Cells[e.ColumnIndex]; string text = (string)cell.FormattedValue; if (string.IsNullOrEmpty(text)) return; Size size = TextRenderer.MeasureText(text, view.Font); row.Height = Math.Max(size.Height + _rowMargins, row.Height); } private static void DataGridViewOnCellPainting(object sender, DataGridViewCellPaintingEventArgs e) { if (e.ColumnIndex == -1 || e.RowIndex == -1 || e.FormattedValue == null) { return; } e.Paint(e.ClipBounds, DataGridViewPaintParts.All ^ DataGridViewPaintParts.ContentForeground); DataGridView view = sender as DataGridView; string textToDisplay = TrimTextToFit(string.Format("{0}", e.FormattedValue), (int)(e.CellBounds.Width * 0.96) - 3, e.CellBounds.Height - _rowMargins, view.Font); bool selected = view.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; SolidBrush brush = new SolidBrush(selected ? e.CellStyle.SelectionForeColor : e.CellStyle.ForeColor); e.Graphics.DrawString(textToDisplay, view.Font, brush, e.CellBounds.X + 1, e.CellBounds.Y + _rowMargins / 2); e.Handled = true; } private static string TrimTextToFit(string text, int contentWidth, int contentHeight, Font font) { Size size = TextRenderer.MeasureText(text, font); if (size.Width < contentWidth && size.Height < contentHeight) { return text; } int i = 0; StringBuilder sb = new StringBuilder(); while (i < text.Length) { sb.Append(text[i++]); size = TextRenderer.MeasureText(sb.ToString(), font); if (size.Width < contentWidth) continue; sb.Append("..."); while (sb.Length > 3 && size.Width >= contentWidth) { sb.Remove(sb.Length - 4, 1); size = TextRenderer.MeasureText(sb.ToString(), font); } while (i < text.Length && text[i] != Environment.NewLine[0]) { i++; } } string res = sb.ToString(); if (size.Height <= contentHeight) { return res; } string[] lines = res.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); i = lines.Length; while (i > 1 && size.Height > contentHeight) { res = string.Join(Environment.NewLine, lines, 0, --i); size = TextRenderer.MeasureText(res, font); } return res; } } 
  if ((!e.Value.Equals("OK")) && e.ColumnIndex == 6) { e.CellStyle.WrapMode = DataGridViewTriState.True; //dgvObjetivos.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; dgvObjetivos.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; } 

http://kshitijsharma.net/2010/08/23/showing-multiline-string-in-a-datagridview-cell/