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,AutoSizeRowsMo​​de=AllCells

通过省略号截断,但删除所有 CRLF 并仅显示一行

WrapMode=False,AutoSizeRowsMo​​de=None

行高设置为所需值,但截断与上述相同

WrapMode=True,AutoSizeRowsMo​​de=AllCells

不截断,显示所有文本并且调整单元格的高度以适合所有文本

WrapMode=True,AutoSizeRowsMo​​de=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()