[英]Wrap a row in DataGridView
我正在嘗試創建一個聊天機器人。 我會很誠實,UI不是我的強項。 我正在邏輯部分的聊天機器人的后端工作,但是為了測試我需要一個適當的工作UI。 所以,我選擇更容易使用winforms。 我創建了一個單列DataGridView,並且在聊天窗口底部的文本框中寫的所有文本都將顯示為DataGridView行。 winform錨定在各個方向生長。 因此,當我加載exe時,它顯示為一個微型窗口,當我最大化它時,DataGridView部分和文本框相應地增長。
當我鍵入一個長字符串並且winform未處於最大化狀態時,文本不會包含在可見區域的行中。 它水平延伸,因此在屏幕上顯然不可見。 當我最大化窗口時,我可以看到文本。 當我給出一個非常長的字符串並最大化窗口時,只有那么多字符串顯示在行中,因為它可以適合屏幕大小。
我想做的是:我希望文本自動換行,這樣無論我的窗口是最大化還是最小化,我都可以看到窗口中的整個字符串都是包裝格式。
我嘗試過的:
dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
DataGridViewTextBox
使用word-break執行換行。 這意味着如果你有一個長文本,那么中斷將僅適用於單詞的結尾。 根據您的要求,在換行時需要進行字符分解。 為此,您需要創建自定義單元格並以這種方式執行字符拆分換行:
重寫GetPreferredSize
方法,根據字符中斷自動換行計算單元格/行的高度。 為此您可以使用Graphics.MeasureString
方法。
使用Graphics.DrawString
方法覆蓋Paint
方法以使用字符中斷繪制包裝的字符串。
您可以執行以下設置:
要為列使用DataGridView
的寬度,應將其AutoSizeMode
設置為Fill
。 這樣,您的列寬將填充網格,並將根據網格大小更改其大小。 此外,如果您有多個列,則可以設置FillWeight
來控制列大小相對於其他列的百分比。
要將文本包裝在列中,您應該將列的DefaultCellStyle.WrapMode
設置為DataGridViewTriState.True
。
要使行自動調整大小,您應將DataGridView
AutoSizeRowMode
設置為DataGridViewAutoSizeRowsMode.AllCells
。
注冊我們創建的自定義單元格作為列的CellTemplate
。
MyDataGridViewTextBoxCell
此單元格使用字符分隔而不是分詞來執行文本換行。
public class MyDataGridViewTextBoxCell:DataGridViewTextBoxCell
{
protected override Size GetPreferredSize(Graphics graphics,
DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
{
if(cellStyle.WrapMode== DataGridViewTriState.True && this.RowIndex>=0)
{
var value= string.Format("{0}", this.FormattedValue);
using (var g = this.OwningColumn.DataGridView.CreateGraphics())
{
var r = g.MeasureString(value, cellStyle.Font, this.OwningColumn.Width )
.ToSize();
r.Width += cellStyle.Padding.Left + cellStyle.Padding.Right;
r.Height += cellStyle.Padding.Top + cellStyle.Padding.Bottom;
return r;
}
}
else
{
return base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize);
}
}
protected override void Paint(Graphics graphics, Rectangle clipBounds,
Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
object value, object formattedValue, string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value,
formattedValue, errorText, cellStyle, advancedBorderStyle,
paintParts & ~ DataGridViewPaintParts.ContentForeground);
graphics.DrawString(string.Format("{0}", formattedValue),
cellStyle.Font, Brushes.Black, cellBounds);
}
}
例
public class Model
{
public string Text { get; set; }
}
BindingList<Model> list = new BindingList<Model>();
private void Form1_Load(object sender, EventArgs e)
{
var column1 = new DataGridViewTextBoxColumn();
column1.CellTemplate = new MyDataGridViewTextBoxCell();
column1.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
column1.DataPropertyName = "Text";
column1.DefaultCellStyle = new DataGridViewCellStyle();
column1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
column1.HeaderText = "Text";
column1.Name = "column1";
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dataGridView1.Columns.Add(column1);
this.dataGridView1.DataSource = list;
}
private void button1_Click(object sender, EventArgs e)
{
list.Add(new Model() { Text = textBox1.Text });
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.