Это пользовательское поле со списком.Добавьте это в свой проект, и вы можете добавить его в форму Windows и использовать его как обычный ComboBox
CustomComboBox
<ToolboxItem(true)> _
<ToolboxBitmap(GetType(ComboBox))> _
partial public class CustomComboBox
Inherits ComboBox
sub New()
DrawMode = DrawMode.OwnerDrawFixed
DropDownStyle = ComboBoxStyle.DropDownList
ItemHeight = 26
DropDownHeight = ItemHeight * 6
end sub
protected Overrides sub OnDrawItem( e As DrawItemEventArgs)
if (e.Index >= 0) then
e.DrawBackground()
e.DrawFocusRectangle()
using b as New SolidBrush(ForeColor)
dim name as String = Items(e.Index).ToString()
dim textLeft as Int32 = e.Bounds.Left + 3
dim textTop as Int32 = e.Bounds.Top + (e.Bounds.Height / 2) - (Font.Height / 2)
dim textWidth as Int32 = e.Bounds.Width - e.Bounds.Width
dim textHeight as Int32 = e.Bounds.Height
Dim textTarget as Rectangle = new Rectangle(textLeft, textTop, textWidth, textHeight)
e.Graphics.DrawString(name, Font, b, textTarget)
end using
end if
end sub
End Class
Чтобы изменить высотуComboBox
и количество места, выделенного каждому элементу внутри него, измените значение ItemHeight
в конструкторе.
Чтобы поместить это в DataGridView, вам нужно создать пользовательскую ячейку, столбец и EditControl.Все три относительно легко создать, как вы можете видеть из кода ниже.
CustomComboBoxCell
public class CustomComboBoxCell
Inherits DataGridViewTextBoxCell
public overrides sub InitializeEditingControl(rowIndex As Int32 , initialFormattedValue As Object , dataGridViewCellStyle As DataGridViewCellStyle )
' Set the value of the editing control to the current cell value.
mybase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
dim ctl as CustomComboBoxEditControl = CType(DataGridView.EditingControl, CustomComboBoxEditControl)
Dim col As CustomComboBoxColumn = CType(DataGridView.Columns(DataGridView.CurrentCell.ColumnIndex), CustomComboBoxColumn)
Dim row As DataGridViewRow = CType(DataGridView.Rows(DataGridView.CurrentCell.RowIndex), DataGridViewRow)
ctl.DataSource = col.DataSource
ctl.Height = DataGridView.RowTemplate.Height
ctl.ItemHeight = row.Height - 6
' Use the default row value when Value property is null.
if (me.Value is Nothing OrElse me.Value is DBNull.Value)
ctl.Text = me.DefaultNewRowValue
else
ctl.Text = me.Value
end if
end sub
public overrides ReadOnly property EditType() As Type
get
return GetType(CustomComboBoxEditControl)
end get
end Property
public overrides readonly property FormattedValueType () as Type
get
return GetType(String)
end get
end Property
public overrides ReadOnly property ValueType() As Type
get
return GetType(String)
End Get
end property
public overrides ReadOnly property DefaultNewRowValue() as Object
get
return String.Empty
end Get
end Property
protected Overrides sub Paint(graphics As Graphics , _
clipBounds As Rectangle , _
cellBounds As Rectangle , _
rowIndex As int32 , _
cellState As DataGridViewElementStates , _
value As Object , _
formattedValue As Object , _
errorText As String , _
cellStyle As DataGridViewCellStyle , _
advancedBorderStyle As DataGridViewAdvancedBorderStyle , _
paintParts As DataGridViewPaintParts)
'base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
mybase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, String.Empty, String.Empty, errorText, cellStyle, advancedBorderStyle, paintParts)
if (TypeOf value is string)
Dim valueString As String = Convert.ToString(value)
if (not String.IsNullOrEmpty(valueString))
Dim b As Brush = new SolidBrush(cellStyle.ForeColor)
Dim textLeft as Int32 = cellBounds.Left + 6
Dim textTop as Int32 = cellBounds.Top + (cellBounds.Height / 2) - (cellStyle.Font.Height / 2)
Dim textWidth as Int32 = cellBounds.Width - cellBounds.Width
Dim textHeight as Int32 = cellBounds.Height
Dim textTarget As Rectangle = new Rectangle(textLeft, textTop, textWidth, textHeight)
graphics.DrawString(valueString, cellStyle.Font, b, textTarget)
end if
end if
end sub
end class
CustomComboBoxColumn
public class CustomComboBoxColumn
Inherits DataGridViewColumn
sub new ()
mybase.new(New CustomComboBoxCell())
end sub
public Property DataSource() as Object
public overrides property CellTemplate() As DataGridViewCell
get
return mybase.CellTemplate
end get
set
Dim targetType as Type = GetType(CustomComboBoxCell)
' Ensure that the cell used for the template is a CustomComboBoxCell.
if (not IsNothing(value) AndAlso
not value.GetType().IsAssignableFrom(targetType))
Dim errorMessage As String = $"CellTemplate must be of the type {targetType}."
throw new InvalidCastException(errorMessage)
end if
mybase.CellTemplate = value
end set
End Property
public overrides Function Clone() as Object
Dim retVal As CustomComboBoxColumn = CType(mybase.Clone(), CustomComboBoxColumn)
retVal.DataSource = me.DataSource
return retVal
End Function
end class
CustomComboBoxEditControl
<ToolboxItem(false)>
public class CustomComboBoxEditControl
Inherits CustomComboBox
Implements IDataGridViewEditingControl
public Sub New ()
IDataGridViewEditingControl_EditingControlFormattedValue = false
end sub
Public Property IDataGridViewEditingControl_EditingControlDataGridView As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
Public Property IDataGridViewEditingControl_EditingControlValueChanged As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
Public Property IDataGridViewEditingControl_EditingControlRowIndex As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
Public Function IDataGridViewEditingControl_GetEditingControlFormattedValue(context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
return IDataGridViewEditingControl_EditingControlFormattedValue
End Function
Public ReadOnly Property IDataGridViewEditingControl_RepositionEditingControlOnValueChange As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
get
return False
End Get
end property
Public ReadOnly Property IDataGridViewEditingControl_EditingPanelCursor As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
get
Return MyBase.Cursor
End Get
end Property
Public Property IDataGridViewEditingControl_EditingControlFormattedValue As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
get
return me.selectedItem
End Get
Set(value As Object)
me.SelectedItem = value
End Set
end property
Public Sub IDataGridViewEditingControl_ApplyCellStyleToEditingControl(dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
me.Font = dataGridViewCellStyle.Font
me.ForeColor = dataGridViewCellStyle.ForeColor
me.BackColor = dataGridViewCellStyle.BackColor
End Sub
Public Function IDataGridViewEditingControl_EditingControlWantsInputKey(keyData As Keys, dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey
select (keydata and Keys.KeyCode)
case Keys.Escape, Keys.Up, Keys.Down, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
return true
Case else
return Not dataGridViewWantsInputKey
end Select
End Function
Public Sub IDataGridViewEditingControl_PrepareEditingControlForEdit(selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
' Do nothing
End Sub
protected overrides sub OnSelectedValueChanged( eventArgs as EventArgs)
' Notify the DataGridView that the contents of the cell have changed.
Me.IDataGridViewEditingControl_EditingControlValueChanged = true
Me.IDataGridViewEditingControl_EditingControlDataGridView.NotifyCurrentCellDirty(true)
end sub
End Class
Затем он добавляется в форму с помощью:
grid.AutoGenerateColumns = false
grid.RowTemplate.Height = 45
Dim customComboBoxColumn as new CustomComboBoxColumn()
customComboBoxColumn.DataPropertyName = "Custom Drop Down"
customComboBoxColumn.DataSource = DropDownItems1
dataGridView1.Columns.Add(customComboBoxColumn)
Dim regularComboBoxColumn as new DataGridViewComboBoxColumn()
regularComboBoxColumn.DataPropertyName = "Regular Drop Down"
regularComboBoxColumn.DataSource = DropDownItems2
dataGridView1.Columns.Add(regularComboBoxColumn)
Вот как это выглядит при размещении в форме,Левая колонка - это новый CustomComboBoxColumn
, а справа - стандарт DataGridViewComboBoxColumn