Windows Forms: режим обтекания ячейки для отображения адаптивного многоточия - PullRequest
0 голосов
/ 29 мая 2018

Я использую Datagridview для Windows Forms для отображения некоторого (длинного) текста.(Код PowerShell, но проблема связана с режимом переноса ячеек)

$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
}

Я использую перенос ячеек и AutosizeRowMode, но я не нашел способа отобразить ячейку DGV доопределенную точку, затем обрезать с помощью многоточия при превышении размера ячейки.Чего я хотел бы добиться, так это: (графическое редактирование)

Desired

, но до сих пор я не смог этого сделать:

WrapMode = False, AutoSizeRowsMode = AllCells

усекает по многоточию, но удаляет все CRLF и отображает только одну строку

WrapMode=False,AutoSizeRowsMode=AllCells

WrapMode =False, AutoSizeRowsMode = Нет

Высота строки установлена ​​на желаемое значение, но в остальном усечение такое же, как указано выше

WrapMode=False,AutoSizeRowsMode=None

WrapMode = True, AutoSizeRowsMode= AllCells

Без усечения, отображается весь текст, а ячейка адаптируется по высоте для размещения всего текста

WrapMode=True,AutoSizeRowsMode=AllCells

WrapMode= True, AutoSizeRowsMode = Нет

Высота остается неизменной, но усечение не выполняется.

WrapMode=True,AutoSizeRowsMode=None

Я пытаюсь выполнитьчтобы строки были изменены до максимального размера, после чего текст должен быть обрезан многоточием [...]

Я уже пробовал обрезать содержимое, но у него есть побочный эффект: когда пользователь КОПИРУЕТ содержимое ячейки, содержимое ячейки пропускает всю усеченную часть (конечно), поэтому это нереальный вариант ..

Большое спасибо

1 Ответ

0 голосов
/ 30 мая 2018

Вам нужно обработать 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
}

enter image description here

Полный пример

Вот полный рабочий пример 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()
...