Попробуйте это.
Вы можете переключать FontStyle.Strikeout
любой из ячеек, которые содержат raw значения (значения, не сгенерированные расчетом), либо используяALT + левая кнопка мыши или нажатие клавиши (здесь обрабатывается Keys.S
).
Эти комбинации можно сохранить как в файле конфигурации.
Примечание: если вы не нажметеЕсли вы не хотите использовать ключевые модификаторы, вы должны установить EditMode DataGridView на DataGridViewEditMode.EditOnF2
или DataGridViewEditMode.EditProgrammatically
, в противном случае событие KeyDown не вызываетсяи текущая ячейка всегда будет переходить в режим редактирования.
Поскольку EditProgrammatically
добавляет сложность (вам нужно обрабатывать множество случаев, в противном случае возникают исключения), я установил для него значение EditOnF2
(поэтому вам нужно нажатьF2
для входа в режим редактирования). Если вместо этого вы выберете модификатор Key + Key (например, Control + K ), вы можете оставить значение по умолчанию EditMode
.
Существует метод, который оценивает текущий стиль шрифта:
Private Function GetCellFont(cell As DataGridViewCell) As Font
Return If(IsNothing(cell.Style.Font), cell.InheritedStyle.Font, cell.Style.Font)
End Function
, поскольку ячейка может не иметь своего собственного набора шрифтов. Это может быть унаследовано. В этом случае [DataGridViewCell].Style.Font
равно нулю (nothing
).
Подписаться на события DataGridView в конструкторе формы или иным образом перед привязкой DataSource:
AddHandler DataGridView1.CellFormatting, AddressOf dgv_CellFormatting
AddHandler DataGridView1.CellMouseDown, AddressOf dgv_CellMouseDown
AddHandler DataGridView1.CellValueChanged, AddressOf dgv_CellValueChanged
AddHandler DataGridView1.KeyDown, AddressOf dgv_KeyDown
В примере кода (я добавил анимацию, чтобы настройка была более понятной),первые три столбца содержат десятичные значения, последние два представляют суммы и средние значения всех ячеек строки, для которых не установлен стиль StrikeOut
.
Столбец «Средний» существует только дляпокажите использование decimal.Round () , чтобы определить количество десятичных знаков для рассмотрения.
При переключении стиля шрифта ячейки или изменении значения соответствующие вычисленные значения (столбцы 3 и 4) обновляются.
Изменение значения, вызванное редактированием ячейки, обрабатывается событием CellValueChanged , вызывающим метод Form Validate () , который заставляет DataGridView форматировать ячейки, которыеиметь статус Dirty
.
Private Sub dgv_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs)
If (e.RowIndex < 0) OrElse (e.ColumnIndex < 3) Then Return
Dim value As Decimal = CalculateValues(e.ColumnIndex, e.RowIndex, DirectCast(sender, DataGridView))
e.Value = value
End Sub
Private Sub dgv_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs)
If e.ColumnIndex > 2 Then Return
Validate()
End Sub
Private Sub dgv_CellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs)
If (e.RowIndex < 0) OrElse ((e.ColumnIndex < 0) OrElse (e.ColumnIndex > 2)) Then Return
If (ModifierKeys <> Keys.Alt) OrElse (e.Button <> MouseButtons.Left) Then Return
Dim dgv = DirectCast(sender, DataGridView)
ToggleCellFontStyle(dgv(e.ColumnIndex, e.RowIndex))
End Sub
Private Sub dgv_KeyDown(sender As Object, e As KeyEventArgs)
Dim currentCell As DataGridViewCell = DirectCast(sender, DataGridView).CurrentCell
If e.KeyValue = Keys.S AndAlso currentCell IsNot Nothing Then
e.SuppressKeyPress = True
If (currentCell.ColumnIndex < 0) OrElse (currentCell.ColumnIndex > 2) Then Return
ToggleCellFontStyle(DataGridView1.CurrentCell)
End If
End Sub
Private Function CalculateValues(columnIndex As Integer, rowIndex As Integer, dgv As DataGridView) As Decimal
Dim sum As Decimal = 0.0D
Dim avg As Decimal = 0.0D
Dim valuesCounted As Integer = 0
For col As Integer = 0 To 2
Dim fStyle = GetCellFont(dgv(col, rowIndex)).Style And FontStyle.Strikeout
If fStyle <> FontStyle.Strikeout Then
valuesCounted += 1
Dim cellValue = dgv(col, rowIndex).Value
sum += CDec(If(cellValue Is DBNull.Value, 0.00D, cellValue))
End If
Next
avg = Decimal.Round(If(valuesCounted > 0, sum / valuesCounted, 0.00D), 3)
Return If(columnIndex = 3, sum, avg)
End Function
Private Sub ToggleCellFontStyle(cell As DataGridViewCell)
Dim cellFont As Font = GetCellFont(cell)
Dim cellFontStyle As FontStyle = cellFont.Style
Dim isStrikeOut = (cellFontStyle And FontStyle.Strikeout) = FontStyle.Strikeout
cellFontStyle = If(isStrikeOut, cellFontStyle Xor FontStyle.Strikeout, cellFontStyle Or FontStyle.Strikeout)
cell.Style.Font?.Dispose()
cell.Style.Font = New Font(cellFont, cellFontStyle)
End Sub
Private Function GetCellFont(cell As DataGridViewCell) As Font
Return If(IsNothing(cell.Style.Font), cell.InheritedStyle.Font, cell.Style.Font)
End Function