Windows Forms:单元格环绕模式显示自适应省略号
Windows Forms: Cell Wrapping mode to display adaptive ellipsis
我正在使用 Windows Forms Datagridview 来显示一些(长)文本。 (代码为PowerShell,但问题与Cell Wrapping模式有关)
$TestGridView = New-Object System.Windows.Forms.DataGridView -Property @{
Name="TestDataGridView"
AllowUserToAddRows = $False
AllowUserToDeleteRows = $False
Location = "14,225"
Size = "1041,328"
TabIndex = 1
DefaultCellStyle= @{WrapMode ='True'}
RowHeadersVisible=$False
AutoSizeColumnsMode='Fill'
AutoSizeRowsMode = 'AllCells'
Anchor = 'Left, Right, Top, Bottom'
DefaultCellStyle.Padding = new-object Windows.Forms.Padding -a 2
}
我正在使用 Cell Wrapping 和 AutosizeRowMode,但我发现无法让 DGV 单元格显示到某个点,然后在超过单元格大小时用省略号截断。
我想要完成的是:(图形编辑)
但到目前为止,我一直无法这样做:
WrapMode=False,AutoSizeRowsMode=AllCells
通过省略号截断,但删除所有 CRLF 并仅显示一行
WrapMode=False,AutoSizeRowsMode=None
行高设置为所需值,但截断与上述相同
WrapMode=True,AutoSizeRowsMode=AllCells
不截断,显示所有文本并且调整单元格的高度以适合所有文本
WrapMode=True,AutoSizeRowsMode=None
高度保持原样,但未执行截断。
我想要完成的是将行的大小调整到最大,之后文本应该被省略号截断 [...]
我已经尝试过截断内容,但它有不利的副作用,即当用户复制单元格内容时,单元格内容会丢失所有被截断的部分(当然),因此这不是一个可行的选择..
非常感谢
您需要自己处理 CellPainting
事件并通过应用自动换行和省略号自己绘制文本:
Function dgv_CellPainting{[CmdletBinding()]param(
[parameter()]
[Object]$sender,
[parameter()]
[System.Windows.Forms.DataGridViewCellPaintingEventArgs]$e
)
#Don't process if it's not the column which we want or it's a header row
if (($e.ColumnIndex -ne 0) -or ($e.RowIndex -lt 0)){ return }
#Paint all parts but text
$e.Paint($e.CellBounds, [System.Windows.Forms.DataGridViewPaintParts]::All `
-band (-bnot([System.Windows.Forms.DataGridViewPaintParts]::ContentForeground)))
$color = $e.CellStyle.ForeColor
if ($sender.Rows[$e.RowIndex].Cells[$e.ColumnIndex].Selected -eq $true){
$color = $e.CellStyle.SelectionForeColor}
#Paint text
[System.Windows.Forms.TextRenderer]::DrawText($e.Graphics, $e.FormattedValue, `
$e.CellStyle.Font, $e.CellBounds, $color, `
[System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor `
[System.Windows.Forms.TextFormatFlags]::TextBoxControl -bor `
[System.Windows.Forms.TextFormatFlags]::WordBreak -bor `
[System.Windows.Forms.TextFormatFlags]::EndEllipsis)
#Event handled, stop default processing
$e.Handled = $true
}
完整示例
这是一个完整的 PowerShell 示例。您可以尝试调整列或行的大小来查看效果。
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.Add_Load({form_Load -sender $form -e $_})
$dgv = New-Object System.Windows.Forms.DataGridView
$dgv.Dock = [System.Windows.Forms.DockStyle]::Fill
$dgv.RowTemplate.Height = 50
$dgv.Add_CellPainting({dgv_CellPainting -sender $dgv -e $_})
$form.Controls.Add($dgv)
Function form_Load {[CmdletBinding()]param(
[parameter()]
[Object]$sender,
[parameter()]
[System.EventArgs]$e
)
$dt = New-Object System.Data.DataTable
$dt.Columns.Add("Column1")
$dt.Rows.Add("Lorem ipsum dolor sit amet, " + `
"wisi fierent fabellas pri et, eum aeterno volumus no.")
$dgv.DataSource = $dt
#Enable multiline editing
$dgv.Columns[0].DefaultCellStyle.WrapMode = `
[System.Windows.Forms.DataGridViewTriState]::True
}
Function dgv_CellPainting{[CmdletBinding()]param(
[parameter()]
[Object]$sender,
[parameter()]
[System.Windows.Forms.DataGridViewCellPaintingEventArgs]$e
)
#Don't process if it's not the column which we want or it's a header row
if (($e.ColumnIndex -ne 0) -or ($e.RowIndex -lt 0)){ return }
#Paint all parts but text
$e.Paint($e.CellBounds, [System.Windows.Forms.DataGridViewPaintParts]::All `
-band (-bnot([System.Windows.Forms.DataGridViewPaintParts]::ContentForeground)))
$color = $e.CellStyle.ForeColor
if ($sender.Rows[$e.RowIndex].Cells[$e.ColumnIndex].Selected -eq $true){
$color = $e.CellStyle.SelectionForeColor}
#Paint text
[System.Windows.Forms.TextRenderer]::DrawText($e.Graphics, $e.FormattedValue, `
$e.CellStyle.Font, $e.CellBounds, $color, `
[System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor `
[System.Windows.Forms.TextFormatFlags]::TextBoxControl -bor `
[System.Windows.Forms.TextFormatFlags]::WordBreak -bor `
[System.Windows.Forms.TextFormatFlags]::EndEllipsis)
#Event handled, stop default processing
$e.Handled = $true
}
$form.ShowDialog()
$form.Dispose()
我正在使用 Windows Forms Datagridview 来显示一些(长)文本。 (代码为PowerShell,但问题与Cell Wrapping模式有关)
$TestGridView = New-Object System.Windows.Forms.DataGridView -Property @{
Name="TestDataGridView"
AllowUserToAddRows = $False
AllowUserToDeleteRows = $False
Location = "14,225"
Size = "1041,328"
TabIndex = 1
DefaultCellStyle= @{WrapMode ='True'}
RowHeadersVisible=$False
AutoSizeColumnsMode='Fill'
AutoSizeRowsMode = 'AllCells'
Anchor = 'Left, Right, Top, Bottom'
DefaultCellStyle.Padding = new-object Windows.Forms.Padding -a 2
}
我正在使用 Cell Wrapping 和 AutosizeRowMode,但我发现无法让 DGV 单元格显示到某个点,然后在超过单元格大小时用省略号截断。 我想要完成的是:(图形编辑)
但到目前为止,我一直无法这样做:
WrapMode=False,AutoSizeRowsMode=AllCells
通过省略号截断,但删除所有 CRLF 并仅显示一行
WrapMode=False,AutoSizeRowsMode=None
行高设置为所需值,但截断与上述相同
WrapMode=True,AutoSizeRowsMode=AllCells
不截断,显示所有文本并且调整单元格的高度以适合所有文本
WrapMode=True,AutoSizeRowsMode=None
高度保持原样,但未执行截断。
我想要完成的是将行的大小调整到最大,之后文本应该被省略号截断 [...]
我已经尝试过截断内容,但它有不利的副作用,即当用户复制单元格内容时,单元格内容会丢失所有被截断的部分(当然),因此这不是一个可行的选择..
非常感谢
您需要自己处理 CellPainting
事件并通过应用自动换行和省略号自己绘制文本:
Function dgv_CellPainting{[CmdletBinding()]param(
[parameter()]
[Object]$sender,
[parameter()]
[System.Windows.Forms.DataGridViewCellPaintingEventArgs]$e
)
#Don't process if it's not the column which we want or it's a header row
if (($e.ColumnIndex -ne 0) -or ($e.RowIndex -lt 0)){ return }
#Paint all parts but text
$e.Paint($e.CellBounds, [System.Windows.Forms.DataGridViewPaintParts]::All `
-band (-bnot([System.Windows.Forms.DataGridViewPaintParts]::ContentForeground)))
$color = $e.CellStyle.ForeColor
if ($sender.Rows[$e.RowIndex].Cells[$e.ColumnIndex].Selected -eq $true){
$color = $e.CellStyle.SelectionForeColor}
#Paint text
[System.Windows.Forms.TextRenderer]::DrawText($e.Graphics, $e.FormattedValue, `
$e.CellStyle.Font, $e.CellBounds, $color, `
[System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor `
[System.Windows.Forms.TextFormatFlags]::TextBoxControl -bor `
[System.Windows.Forms.TextFormatFlags]::WordBreak -bor `
[System.Windows.Forms.TextFormatFlags]::EndEllipsis)
#Event handled, stop default processing
$e.Handled = $true
}
完整示例
这是一个完整的 PowerShell 示例。您可以尝试调整列或行的大小来查看效果。
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.Add_Load({form_Load -sender $form -e $_})
$dgv = New-Object System.Windows.Forms.DataGridView
$dgv.Dock = [System.Windows.Forms.DockStyle]::Fill
$dgv.RowTemplate.Height = 50
$dgv.Add_CellPainting({dgv_CellPainting -sender $dgv -e $_})
$form.Controls.Add($dgv)
Function form_Load {[CmdletBinding()]param(
[parameter()]
[Object]$sender,
[parameter()]
[System.EventArgs]$e
)
$dt = New-Object System.Data.DataTable
$dt.Columns.Add("Column1")
$dt.Rows.Add("Lorem ipsum dolor sit amet, " + `
"wisi fierent fabellas pri et, eum aeterno volumus no.")
$dgv.DataSource = $dt
#Enable multiline editing
$dgv.Columns[0].DefaultCellStyle.WrapMode = `
[System.Windows.Forms.DataGridViewTriState]::True
}
Function dgv_CellPainting{[CmdletBinding()]param(
[parameter()]
[Object]$sender,
[parameter()]
[System.Windows.Forms.DataGridViewCellPaintingEventArgs]$e
)
#Don't process if it's not the column which we want or it's a header row
if (($e.ColumnIndex -ne 0) -or ($e.RowIndex -lt 0)){ return }
#Paint all parts but text
$e.Paint($e.CellBounds, [System.Windows.Forms.DataGridViewPaintParts]::All `
-band (-bnot([System.Windows.Forms.DataGridViewPaintParts]::ContentForeground)))
$color = $e.CellStyle.ForeColor
if ($sender.Rows[$e.RowIndex].Cells[$e.ColumnIndex].Selected -eq $true){
$color = $e.CellStyle.SelectionForeColor}
#Paint text
[System.Windows.Forms.TextRenderer]::DrawText($e.Graphics, $e.FormattedValue, `
$e.CellStyle.Font, $e.CellBounds, $color, `
[System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor `
[System.Windows.Forms.TextFormatFlags]::TextBoxControl -bor `
[System.Windows.Forms.TextFormatFlags]::WordBreak -bor `
[System.Windows.Forms.TextFormatFlags]::EndEllipsis)
#Event handled, stop default processing
$e.Handled = $true
}
$form.ShowDialog()
$form.Dispose()