2015-01-09 2 views
1

Я создал собственный элемент управления DataGridViewColumn вместе с элементами управления DataGridViewCell. Идея состоит в том, чтобы динамически создавать содержимое ячейки, которая состоит из серии кнопок с возможностью щелчка, при привязке данных. Количество и виды кнопок зависят от переданного значения данных.Добавить кнопки для кликов в пользовательский элемент управления DataGridViewCell

Для этого я переопределяю метод Paint DataGridViewCell и проверяю formattedValue на его содержимое и соответственно рисуем кнопки. Тем не менее, эти кнопки «мертвы» и не доступны для кликов, поэтому вопрос заключается в том, как сделать их доступными для кликов, например, как добавить обработчик события click?

Должен ли я переопределить метод OnClick ячейки, а затем попытаться точно определить, какая кнопка нажата? Возможно ли это? Есть ли лучшие способы?

Это то, что я получил до сих пор:

Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, cellState As DataGridViewElementStates, value As Object, formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts) 

    MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts) 

    Dim cellBackground As New SolidBrush(cellStyle.BackColor) 
    graphics.FillRectangle(cellBackground, cellBounds) 
    cellBackground.Dispose() 

    PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle) 

    Dim sValue As String = formattedValue.ToString() 

    If (sValue.Contains("ViewAsPDF")) Then 

     Dim buttonArea As Rectangle = cellBounds 
     Dim buttonAdjustment As Rectangle = Me.BorderWidths(advancedBorderStyle) 
     buttonArea.X += buttonAdjustment.X 
     buttonArea.Y += buttonAdjustment.Y 
     buttonArea.Height -= buttonAdjustment.Height 
     buttonArea.Width -= buttonAdjustment.Width 
     buttonArea.Width = buttonArea.Width/4 
     ButtonRenderer.DrawButton(graphics, buttonArea, PushButtonState.Default) 
     TextRenderer.DrawText(graphics, "PDF", Me.DataGridView.Font, buttonArea, SystemColors.ControlText) 

    End If 

    'etcetera 

End Sub 
+0

Что вы подразумеваете под словом "not clickable"? Это дает пользователю ощущение щелчка или обработки событий, похожих на обычную кнопку. – Junaith

+0

Вам не нужно добавлять обработчик для события клика каждой создаваемой вами кнопки? – Supersnake

+0

@Supersnake Да! Но как мне добиться этого в текущей настройке? Я не вижу никакого способа получить кнопку, которую я рисую, поэтому я могу назначить обработчик ... –

ответ

1

Я думаю, что вы, возможно, побрел по ложному пути. Основываясь на приведенном коде, вы просто рисуете ячейки до , выглядите как, они содержат кнопки. Поскольку они не являются объектами, они неспособны поднимать события.

I don't understand ButtonRenderer, if you can't create actual Buttons with it

ButtonRender не создать новый объект кнопки, она предназначена для использования от объектов Button для рисования. Часто подклассифицированная кнопка не будет использовать ее, поскольку она использует существующую тему и стиль, который может быть тем, что вы хотите сделать по-другому (даже DataGridViewButtonCell не использует его - по крайней мере, не напрямую).

Из приведенного кода кажется, что каждая кнопка «на лету» работает каждый раз, а не из какой-либо коллекции или определения. Что делать, если список «действие» должен изменяться в зависимости от строки (например, разные действия для DOC, XLS или строки изображения)? Выполнение этого, казалось бы, требует большого количества кода.


Ваш текущий курс может быть невозможен, но это также не тривиально. You может иметь возможность создавать коллекцию виртуальных кнопок (в основном, Rect с момента ее создания) и визуализировать их так, как вы это делали. Затем в событии со щелчком мыши переведите/отрегулируйте положение X, чтобы увидеть, какой прямоугольник содержит thisPt.X, чтобы определить, какое действие нужно предпринять.

Существуют ли «проблемы», например, что происходит, когда пользователь изменяет размер столбца? Как насчет того, когда список кнопок зависит от другого значения ячейки (DOC vs XLS vs IMG vs PDF)? Для этого потребуется набор наборов кнопок ... и достаточное количество кода.

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


Are there better ways?

Я так думаю.

Простым, существующим решением может быть использование существующего DataGridViewComboBoxColumn для хранения «Действия» или «Действия».Это кажется немного менее загроможден и более дружественным пользователю:

enter image description here

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

' dogs like to go for walks 
Private ActsCan() As String = {"Feed", "Pet", "Bathe", "Brush", "Take for Walk"} 
' no walks or baths for cats 
Private ActsFel() As String = {"Feed", "Pet", "Baby-Talk To", "Brush"} 
' never bathe a Mugwai, comb rather than brush 
Private ActsMug() As String = {"Feed", "Pet", "Baby-Talk To", "Comb"} 
Private ActsGrem() As String = {"Hide From", "Strangle"} 
... 
Private Sub dgv_RowEnter(sender As Object, 
      e As DataGridViewCellEventArgs) Handles dgv.RowEnter 

    Dim dgvCBO As DataGridViewComboBoxCell 
    dgvCBO = CType(dgv.Rows(e.RowIndex).Cells("ColActs"), DataGridViewComboBoxCell) 
    dgvCBO.Items.Clear() 
    Select Case dgv.Rows(e.RowIndex).Cells("colSpecies").Value.ToString 
     Case "Canine" 
      dgvCBO.Items.AddRange(ActsCan) 
     Case "Feline" 
      dgvCBO.Items.AddRange(ActsFel) 
     Case "Mugwai" 
      dgvCBO.Items.AddRange(ActsMug) 
     Case "Gremlin" 
      dgvCBO.Items.AddRange(ActsGrem) 
    End Select 
End Sub 

Класс для инкапсуляции большинства , что может быть приятным для несвязанных DGV. Его можно было бы оптимизировать, чтобы не перестраивать список, когда значение триггера для thisRow совпадает с последним.

+0

Спасибо! Я попробую и отправлю отчет! –

+1

Приоритеты изменились, и у меня не было времени попробовать это, но я совершенно уверен, что это путь вперед! –

+0

Поскольку значение передается ячейке при привязке данных, я смог сделать это с еще меньшим количеством кода, и это выглядит многообещающим! Тем не менее, это дает мне следующую ошибку при привязке данных, поскольку значение ячейки недействительно для привязки к combobox (argumentexception). Примерное значение: «Ярлыки, ActionCard, Where, Archive, InternalComment, More». –

1

Как насчет этого подхода. Только реализация ui.

enter image description here

Смежные вопросы