Блог программиста Еремина Вячеслава Викторовича
(NET) NET (2005 год)

Типизирумый тип столбца в GridView

Мне потребовалось немало времени, чтобы сообразить какие именно классы DataGridView надо унаследовать, чтоб сделать такой интерфейс. Здесь комбешники в ячейках DataGridView отображают данные справочников, ключи которых размещены в главной таблице. Все это реализовано в виде контрола, описанного ниже на этой страничке.

На этом рисунке вы можете увидеть, как конфигурируемая в дизайн-тайме сетка имеет четыре связанных с данными столбца g_ToProjectColumn, g_ToProgrammerColumn, g_ToStateColumn, g_ToTypeColumn (являющиеся фактически ключами (!не индексами!) в связанных с основной таблой справочниках) и четыре несвязанных - g_ImProjectColumn, g_ImProgrammerColumn, g_ImStateColumn, g_ImTypeColumn (с типом TypedDataGridViewColumn), по которым собственно и позиционируются комбешники и, наоборот, значения выбранные в них юзером, сразу же выставляются в связанных с данными полях.




Пользовательский уровень использования этого контрола подразумевает не только вышеприведенные дизайн-таймовые операции, но и следующую простейшую начальную инициализацию контрола:

00001:  Try
00002:     'загружаем комбешники в сетке
00003:     g_ImProjectColumn.LoadFromDS(.PE_Project, .PE_Project.iColumn.Ordinal, .PE_Project.ProjectNameColumn.Ordinal, .PE_Project.ProjectIconColumn.Ordinal)
00004:     g_ImProgrammerColumn.LoadFromDS(.PE_Prog, .PE_Prog.iColumn.Ordinal, .PE_Prog.ProgrammerNameColumn.Ordinal, .PE_Prog.ProgrammerIconColumn.Ordinal)
00005:     g_ImStateColumn.LoadFromDS(.PE_State, .PE_State.iColumn.Ordinal, .PE_State.StateNameColumn.Ordinal, .PE_State.StateIconColumn.Ordinal)
00006:     g_ImTypeColumn.LoadFromDS(.PE_Type, .PE_Type.iColumn.Ordinal, .PE_Type.ErrorNameColumn.Ordinal, .PE_Type.ErrorIconColumn.Ordinal)
00007:     'позиционируем комбешники в сетке
00008:     GridComboRefresh(PE1, GR1, g_ImProjectColumn, g_ToProjectColumn, g_ImProgrammerColumn, g_ToProgrammerColumn, g_ImStateColumn, g_ToStateColumn, g_ImTypeColumn, g_ToTypeColumn)
00009: Catch ex As Exception
00010:     StopRequest = True
00011:     MsgBox("Ошибка загрузки и позиционирования комбешников в сетке." & vbCrLf & ex.Message, MsgBoxStyle.Critical)
00012:     Windows.Forms.Application.Exit()
00013:     Exit Sub
00014: End Try

Описанная здесь функциональность подразумевает, что сетка имеет (в данном случае) четыре BOUND COLUMN (в соответствии с данной диаграммой) и четыре UNBOUND COLUMN (где и размещены ImageCombo):








Теперь перейдем к собственно описанию контрола. Заметьте, что приведенное решение - это пример подхода. Более изящное решение подразумевает создание собственного класса ImDataGridView, который скроет специфику наличия двух связанных и несвязанных с данными полей во внутрь класса DataGridView и утопит туда функциональность модуля ComboInGrid.




Собственно текст основных трех классов контрола приведен ниже:

00001: 'ImageCombo-ячейка сетки - Умеет загрузить комбешник сразу из указанного ДатаСета
00002: '=================================================================================
00003: 
00004: 'Public Class frTest
00005: 
00006: '    Private Sub frTest_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00007: '        PE_StateTableAdapter1.Fill(Pe1.PE_State)
00008: '        Dim TypedColumn As New ComboLib.TypedDataGridViewColumn
00009: '        TypedColumn.LoadFromDS(Pe1.PE_State, Pe1.PE_State.iColumn.Ordinal, 1, 2)
00010: '        G1.Columns.Add(TypedColumn)
00011: '    End Sub
00012: '
00013: '    Private Sub G1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles G1.CellEndEdit
00014: '        If G1.Rows(e.RowIndex).Cells(e.ColumnIndex).GetType.FullName = "ComboLib.TypedDataGridViewCell" Then
00015: '            MsgBox("DataGridView.Rows(" & _
00016: '            e.RowIndex.ToString & ").Cells(" & e.ColumnIndex & ").DataSetKey=" & CType(G1.Rows(e.RowIndex).Cells(e.ColumnIndex), ComboLib.TypedDataGridViewCell).DataSetKey.ToString & _
00017: '            " (" & CType(G1.Columns(e.ColumnIndex), ComboLib.TypedDataGridViewColumn).TableName & ")")
00018: '        End If
00019: '    End Sub
00020: '
00021: '    Private Sub G1_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles G1.DataError
00022: '        '
00023: '    End Sub
00024: 'End Class
00025: 
00026: Imports System.Windows.Forms
00027: Imports System.Drawing
00028: 
00029: Public Class TypedDataGridViewColumn
00030:     Inherits DataGridViewComboBoxColumn
00031: 
00032:     Dim a_ImageList As New ImageList
00033:     'номера полей с ключом, с текстом и с рисунком
00034:     Public Sub LoadFromDS(ByVal DT As Data.DataTable, ByVal DT_KeyColumnNumber As Integer, ByVal DT_TextColumnNumber As Integer, ByVal DT_ImageColumnNumber As Integer)
00035:         a_ImageList.Images.Clear()
00036:         For Each OneRow As Data.DataRow In DT.Rows
00037:             If Not OneRow.RowState = DataRowState.Deleted Then
00038:                 a_ImageList.Images.Add(OneRow(DT_KeyColumnNumber).ToString, FieldToImage(OneRow(DT_ImageColumnNumber)))
00039:                 Me.Items.Add(New ImageComboItem(OneRow(DT_TextColumnNumber), a_ImageList.Images.Count - 1, Nothing, Nothing, OneRow(DT_KeyColumnNumber)))
00040:             End If
00041:         Next
00042:         a_TableName = DT.TableName
00043:     End Sub
00044: 
00045:     Dim a_TableName As String
00046:     'это справочное поле, чтоб не попутать какая именно иконка грузилась в данном столбце
00047:     Public ReadOnly Property TableName() As String
00048:         Get
00049:             Return a_TableName
00050:         End Get
00051:     End Property
00052: 
00053:     Public Property ImageList() As ImageList
00054:         Get
00055:             Return a_ImageList
00056:         End Get
00057:         Set(ByVal value As ImageList)
00058:             a_ImageList = value
00059:         End Set
00060:     End Property
00061: 
00062:     Public Sub New()
00063:         MyBase.New()
00064:         Me.CellTemplate = New TypedDataGridViewCell
00065:     End Sub
00066: 
00067:     Public Overrides Property CellTemplate() As DataGridViewCell
00068:         Get
00069:             Return MyBase.CellTemplate
00070:         End Get
00071:         Set(ByVal value As DataGridViewCell)
00072:             MyBase.CellTemplate = value
00073:         End Set
00074:     End Property
00075: End Class
00076: 
00077: 
00078: Public Class TypedDataGridViewCell
00079:     Inherits DataGridViewComboBoxCell
00080: 
00081:     Dim a_SelectedIndex As Integer = -1
00082:     Public Property SelectedIndex() As Integer
00083:         Get
00084:             Return a_SelectedIndex
00085:         End Get
00086:         Set(ByVal value As Integer)
00087:             a_SelectedIndex = value
00088:         End Set
00089:     End Property
00090: 
00091:     Dim a_DataSetKey As Integer = 0
00092:     Public ReadOnly Property DataSetKey()
00093:         Get
00094:             Return a_DataSetKey
00095:         End Get
00096:     End Property
00097: 
00098:     Public Sub New()
00099:         MyBase.New()
00100:     End Sub
00101: 
00102:     Public Overrides ReadOnly Property EditType() As Type
00103:         Get
00104:             Return GetType(DataGridViewImageComboBoxEditingControl)
00105:         End Get
00106:     End Property
00107: 
00108:     Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
00109:         MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
00110:         Dim control As DataGridViewImageComboBoxEditingControl = CType(DataGridView.EditingControl, DataGridViewImageComboBoxEditingControl)
00111:         control.ImageList = CType(Me.OwningColumn, TypedDataGridViewColumn).ImageList
00112:     End Sub
00113: 
00114:     Public Overrides Sub DetachEditingControl()
00115:         Dim control As DataGridViewImageComboBoxEditingControl = CType(DataGridView.EditingControl, DataGridViewImageComboBoxEditingControl)
00116:         a_SelectedIndex = control.SelectedIndex
00117:         Try
00118:             a_DataSetKey = CType(control.SelectedItem, ImageComboItem).Tag
00119:         Catch x As System.NullReferenceException
00120:             'пощелкали, но ничего не выбрали
00121:         End Try
00122:         MyBase.DetachEditingControl()
00123:     End Sub
00124: 
00125:     <DebuggerStepThrough()> _
00126:     Protected Overrides Sub Paint(ByVal graphics As Graphics, ByVal clipBounds As Rectangle, ByVal cellBounds As Rectangle, ByVal rowIndex As Integer, ByVal elementState As DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As DataGridViewCellStyle, ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, ByVal paintParts As DataGridViewPaintParts)
00127:         MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, "", "", errorText, cellStyle, advancedBorderStyle, paintParts)
00128:         Dim imageHeight As Integer = 0
00129:         Dim imageWidth As Integer = 0
00130:         If (a_SelectedIndex >= 0) Then
00131:             Try
00132:                 Dim image As Image = CType(OwningColumn, TypedDataGridViewColumn).ImageList.Images(a_SelectedIndex)
00133:                 If image.Height > cellBounds.Height Then
00134:                     imageHeight = cellBounds.Height
00135:                 Else
00136:                     imageHeight = image.Height
00137:                 End If
00138:                 imageWidth = (image.Width * (imageHeight / image.Height))
00139:                 If imageWidth > imageHeight Then
00140:                     imageWidth = imageHeight
00141:                 Else
00142:                     imageWidth = imageWidth
00143:                 End If
00144:                 graphics.DrawImage(image, CInt(cellBounds.Left + 2), CInt(cellBounds.Top + ((cellBounds.Height - imageHeight) / 2)), imageWidth, imageHeight)
00145:             Catch except As Exception
00146:                 'ну не отрисовалось - и что делать?
00147:             End Try
00148:         End If
00149:         Dim stringSize As SizeF = graphics.MeasureString(formattedValue.ToString, cellStyle.Font)
00150:         If Not (value Is Nothing) Then
00151:             graphics.DrawString(value.ToString, cellStyle.Font, IIf(Me.Selected, New SolidBrush(Color.White), New SolidBrush(cellStyle.ForeColor)), cellBounds.Left + imageWidth + 3, cellBounds.Top + (cellBounds.Height - stringSize.Height) / 2)
00152:         Else
00153:             graphics.DrawString(formattedValue.ToString(), cellStyle.Font, New SolidBrush(cellStyle.ForeColor), cellBounds.Left + imageWidth + 3, cellBounds.Top + (cellBounds.Height - stringSize.Height) / 2)
00154:         End If
00155:     End Sub
00156: 
00157: 
00158:    'собственно отрисовка раскрывающегося комбешника (по стилям в сетке, а не по стилям в элементе)
00159:     <DebuggerStepThrough()> _
00160:     Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
00161:         MyBase.OnDrawItem(e)
00162:         e.DrawBackground()
00163:         If (e.Index < 0) Then
00164:             Return
00165:         End If
00166:         Dim OneItem As ImageComboItem = CType(Items(e.Index), ImageComboItem)
00167:         Dim imageWidth As Integer = 0
00168:         Dim imageHeight As Integer = 0
00169:         If ((Not (a_ImageList) Is Nothing) _
00170:                     AndAlso ((OneItem.ImageIndex >= 0) _
00171:                     AndAlso (OneItem.ImageIndex < a_ImageList.Images.Count))) Then
00172:             Try
00173:                 Dim image As Image = a_ImageList.Images(OneItem.ImageIndex)
00174:                 If image.Height > e.Bounds.Height Then
00175:                     imageHeight = e.Bounds.Height
00176:                 Else
00177:                     imageHeight = image.Height
00178:                 End If
00179:                 imageWidth = (image.Width * (imageHeight / image.Height))
00180:                 If imageWidth > imageHeight Then
00181:                     imageWidth = imageHeight
00182:                 Else
00183:                     imageWidth = imageWidth
00184:                 End If
00185:                 If ((imageWidth > 0) _
00186:                             AndAlso (imageHeight > 0)) Then
00187:                     e.Graphics.DrawImage(image, e.Bounds.Left, e.Bounds.Top, imageWidth, imageHeight)
00188:                 Else
00189:                     imageWidth = 0
00190:                     imageHeight = 0
00191:                 End If
00192:             Catch except As Exception
00193:                 '
00194:             End Try
00195:         End If
00196:         e.Graphics.DrawString(OneItem.Text, e.Font, New SolidBrush(e.ForeColor), (e.Bounds.Left + (imageWidth + 1)), e.Bounds.Top)
00197:         e.DrawFocusRectangle()
00198:     End Sub
00199: 
00200:     'непонятно как вытащить это событие выше
00201:     'Protected Overrides Sub OnSelectionChangeCommitted(ByVal e As System.EventArgs)
00202:     '    MyBase.OnSelectionChangeCommitted(e)
00203:     'End Sub
00204: 
00205: End Class

Эти классы вписаны непосредственно в структуру DataGridView следующим образом (классы DataGridViewImageComboBoxColumn и DataGridViewImageComboBoxCell в описанной концепции не используются - это просто вариант "голого" отображения комбешника в ячейке сетки без использования описанной здесь функциональности):




Как вы видите тут еще используется в качестве элемента ImageCombo фрагмент моего ImageCombo (никак с сеткой не связанного). Как вы понимаете - это самый нижний уровень функциональности контрола - на уровень ниже вышеприведенной функциональности.

00001: Public Class ImageCombo
00002:     'Этот контрол скрывает детали загрузки рисунков в ImageCombo
00003:     '
00004:     'Дает для потребителя следующий высоуровневый интерфейс:
00005:     '1.   xxxx.ComboImageClear              (при необходимости очистки)
00006:     '2.   xxxx.ComboImageAddPicture         Загрузка рисунков в контрол 
00007:     '    (из VB6-обьекта Picture, из файла, из ресурса)
00008:     '3.   xxxx.ComboItemClear               (при необходимости очистка)
00009:     '4.   xxxx.ComboItemAdd                 (собственно загрузка Combo)        (Text As String, Value As String, ImageKey As String)
00010:     '5.   xxxx.ComboItemSet                 (установка отображаемого элемента) (Value As String)
00011:     '
00012:     'При щелчке юзера на нем, поднимает на вышележащий уровень значение KEY
00013:     'Контрол также используется в NET, поэтому изменение его интерфейсов нежелательно
00014:     '
00015: 
00016:     Dim Combo As New ImageComboInternal
00017: 
00018:     Public Event Changes(ByVal Text As String, ByVal value As String)
00019: 
00020:     Private Sub ImCombo_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
00021:         Me.Controls.Add(Combo)
00022:         AddHandler Combo.SelectedIndexChanged, AddressOf Change
00023:         Combo.Enabled = True
00024:         Combo.ImageList = ImageList1
00025:         Combo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
00026:     End Sub
00027: 
00028: 
00029:     Private Sub Change(ByVal sender As Object, ByVal e As System.EventArgs)
00030:         RaiseEvent Changes(Combo.SelectedItem.text, Combo.SelectedItem.tag)
00031:     End Sub
00032: 
00033:     Public Sub ComboImageClear()
00034:         ImageList1.Images.Clear()
00035:     End Sub
00036: 
00037:     Public Sub ComboImageAddPicture(ByRef ImageKey As String, ByRef FileName As String)
00038:         ImageList1.Images.Add(ImageKey, System.Drawing.Image.FromFile(FileName))
00039:     End Sub
00040: 
00041:     Public Sub ComboImageAddPicture(ByRef ImageKey As String, ByRef Picture As System.Drawing.Image)
00042:         ImageList1.Images.Add(ImageKey, Picture)
00043:     End Sub
00044: 
00045:     Public Sub ComboImageAddPicture(ByRef ImageKey As String, ByRef Icon As System.Drawing.Icon)
00046:         ImageList1.Images.Add(ImageKey, icon)
00047:     End Sub
00048: 
00049:     Public Sub ComboItemClear()
00050:         Combo.Items.Clear()
00051:     End Sub
00052: 
00053:     Public Sub ComboItemAdd(ByRef Text As String, ByRef ImageKey As String)
00054:         Dim i As Integer
00055:         For i = 0 To ImageList1.Images.Count - 1
00056:             If ImageKey = ImageList1.Images.Keys(i) Then
00057:                 Combo.Items.Add(New ImageComboItem(Text, i))
00058:                 Exit Sub
00059:             End If
00060:         Next
00061:     End Sub
00062: 
00063:     Public Sub ComboItemAdd(ByRef Text As String, ByRef ImageKey As String, ByVal Bold As Boolean)
00064:         Dim i As Integer
00065:         For i = 0 To ImageList1.Images.Count - 1
00066:             If ImageKey = ImageList1.Images.Keys(i) Then
00067:                 Combo.Items.Add(New ImageComboItem(Text, i, bold))
00068:                 Exit Sub
00069:             End If
00070:         Next
00071:     End Sub
00072: 
00073:     Public Sub ComboItemAdd(ByRef Text As String, ByRef ImageKey As String, ByVal Bold As Boolean, ByVal Color As System.Drawing.Color)
00074:         Dim i As Integer
00075:         For i = 0 To ImageList1.Images.Count - 1
00076:             If ImageKey = ImageList1.Images.Keys(i) Then
00077:                 Combo.Items.Add(New ImageComboItem(Text, i, Bold, color))
00078:                 Exit Sub
00079:             End If
00080:         Next
00081:     End Sub
00082: 
00083:     Public Sub ComboItemAdd(ByRef Text As String, ByRef ImageKey As String, ByVal Bold As Boolean, ByVal Color As System.Drawing.Color, ByVal Value As Object)
00084:         Dim i As Integer
00085:         For i = 0 To ImageList1.Images.Count - 1
00086:             If ImageKey = ImageList1.Images.Keys(i) Then
00087:                 Combo.Items.Add(New ImageComboItem(Text, i, Bold, Color, Value))
00088:                 Exit Sub
00089:             End If
00090:         Next
00091:     End Sub
00092: 
00093:     Public Sub ComboItemSetKey(ByRef Key As String)
00094:         Dim i As Integer
00095:         For i = 0 To Combo.Items.Count - 1
00096:             If Combo.Items(i).Tag = Key Then Combo.SelectedIndex = i
00097:         Next
00098:     End Sub
00099: 
00100:     Public Sub ComboItemSetValue(ByRef Value As String)
00101:         Dim i As Integer
00102:         For i = 0 To Combo.Items.Count - 1
00103:             If Combo.Items(i).Text = Value Then Combo.Items(i).Selected = True
00104:         Next
00105:     End Sub
00106: 
00107: 
00108:     Private Sub ImCombo_Resize(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Resize
00109:         Combo.Width = MyBase.Width
00110:         Combo.Height = MyBase.Height
00111:     End Sub
00112: End Class
00113: 
00114: 
00115: Public Class ImageComboInternal
00116:     Inherits System.Windows.Forms.ComboBox
00117: 
00118:     Private a_imgs As Windows.Forms.ImageList = New Windows.Forms.ImageList
00119: 
00120:     Public Sub New()
00121:         'set draw mode to owner draw
00122:         Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
00123:     End Sub
00124: 
00125:     'просто копируем ссылку во внутрь контрола
00126:     Public Property ImageList() As Windows.Forms.ImageList
00127:         Get
00128:             Return a_imgs
00129:         End Get
00130:         Set(ByVal value As Windows.Forms.ImageList)
00131:             a_imgs = value
00132:         End Set
00133:     End Property
00134: 
00135:     'drawing process   '&lt;DebuggerStepThrough()&gt; _
00136:     Protected Overloads Overrides Sub OnDrawItem(ByVal e As Windows.Forms.DrawItemEventArgs)
00137:         e.DrawBackground()
00138:         e.DrawFocusRectangle()
00139:         If e.Index < 0 Then
00140:             e.Graphics.DrawString(Me.Text, e.Font, New Drawing.SolidBrush(e.ForeColor), e.Bounds.Left + a_imgs.ImageSize.Width, e.Bounds.Top)
00141:         Else
00142:             If Me.Items(e.Index).GetType Is GetType(ImageComboItem) Then
00143:                 Dim item As ImageComboItem = CType(Me.Items(e.Index), ImageComboItem)
00144:                 Dim forecolor As Drawing.Color = CType(IIf(Not (item.ForeColor = Drawing.Color.FromKnownColor(Drawing.KnownColor.Transparent)), item.ForeColor, e.ForeColor), Drawing.Color)
00145:                 Dim font As Drawing.Font = CType(IIf(item.Bold, New Drawing.Font(e.Font, Drawing.FontStyle.Bold), e.Font), Drawing.Font)
00146:                 If Not (item.ImageIndex = -1) Then
00147:                     Me.ImageList.Draw(e.Graphics, e.Bounds.Left, e.Bounds.Top, item.ImageIndex)
00148:                     e.Graphics.DrawString(item.Text, font, New Drawing.SolidBrush(forecolor), e.Bounds.Left + a_imgs.ImageSize.Width, e.Bounds.Top)
00149:                 Else
00150:                     'наш комбешник, но без иконки
00151:                     e.Graphics.DrawString(item.Text, font, New Drawing.SolidBrush(forecolor), e.Bounds.Left + a_imgs.ImageSize.Width, e.Bounds.Top)
00152:                 End If
00153:             Else
00154:                 'это не наш комбешник, какой-то другой
00155:                 e.Graphics.DrawString(Me.Items(e.Index).ToString, e.Font, New Drawing.SolidBrush(e.ForeColor), e.Bounds.Left + a_imgs.ImageSize.Width, e.Bounds.Top)
00156:             End If
00157:         End If
00158:         MyBase.OnDrawItem(e)
00159:     End Sub
00160: End Class
00161: 
00162: Public Class ImageComboItem
00163: 
00164:     'forecolor: transparent = inherit
00165:     Private a_forecolor As Drawing.Color = Drawing.Color.FromKnownColor(Drawing.KnownColor.Transparent)
00166:     Private a_Bold As Boolean = False
00167:     Private a_imageindex As Integer = -1
00168:     Private a_tag As Object = Nothing
00169:     Private a_text As String = Nothing
00170: 
00171:     Public Sub New()
00172:     End Sub
00173: 
00174:     Public Sub New(ByVal Text As String)
00175:         a_text = Text
00176:     End Sub
00177: 
00178:     Public Sub New(ByVal Text As String, ByVal ImageIndex As Integer)
00179:         a_text = Text
00180:         a_imageindex = ImageIndex
00181:     End Sub
00182: 
00183:     Public Sub New(ByVal Text As String, ByVal ImageIndex As Integer, ByVal Bold As Boolean)
00184:         a_text = Text
00185:         a_imageindex = ImageIndex
00186:         a_Bold = Bold
00187:     End Sub
00188: 
00189:     Public Sub New(ByVal Text As String, ByVal ImageIndex As Integer, ByVal Bold As Boolean, ByVal ForeColor As Drawing.Color)
00190:         a_text = Text
00191:         a_imageindex = ImageIndex
00192:         a_Bold = Bold
00193:         a_forecolor = ForeColor
00194:     End Sub
00195: 
00196:     Public Sub New(ByVal Text As String, ByVal ImageIndex As Integer, ByVal Bold As Boolean, ByVal ForeColor As Drawing.Color, ByVal Tag As Object)
00197:         a_text = Text
00198:         a_imageindex = ImageIndex
00199:         a_Bold = Bold
00200:         a_forecolor = ForeColor
00201:         a_tag = Tag
00202:     End Sub
00203: 
00204:     Public Property ForeColor() As Drawing.Color
00205:         Get
00206:             Return a_forecolor
00207:         End Get
00208:         Set(ByVal value As Drawing.Color)
00209:             a_forecolor = value
00210:         End Set
00211:     End Property
00212: 
00213:     Public Property ImageIndex() As Integer
00214:         Get
00215:             Return a_imageindex
00216:         End Get
00217:         Set(ByVal value As Integer)
00218:             a_imageindex = value
00219:         End Set
00220:     End Property
00221: 
00222:     Public Property Bold() As Boolean
00223:         Get
00224:             Return a_Bold
00225:         End Get
00226:         Set(ByVal value As Boolean)
00227:             a_Bold = value
00228:         End Set
00229:     End Property
00230: 
00231:     Public Property Tag() As Object
00232:         Get
00233:             Return a_tag
00234:         End Get
00235:         Set(ByVal value As Object)
00236:             a_tag = value
00237:         End Set
00238:     End Property
00239: 
00240:     Public Property Text() As String
00241:         Get
00242:             Return a_text
00243:         End Get
00244:         Set(ByVal value As String)
00245:             a_text = value
00246:         End Set
00247:     End Property
00248: 
00249:     Public Overloads Overrides Function ToString() As String
00250:         Return a_text
00251:     End Function
00252: End Class</pre></font>
<p>И, наконец, самый верхний слой контрола, подразумевающий, что сетка имеет (в данном случае) четыре <b>BOUND COLUMN</b> (в соответствии с данной диаграммой) и четыре <b>UNBOUND COLUMN</b> (где и размещены ImageCombo). Повторюсь, более изящное решение подразумевает утапливание и этого слоя во внутрь контрола.</p><br>
<font color="Blue"><pre>
00001: 'здесь собрана конкретная специфика сетки в которой помимо полей с комбешниками TypedDataGridViewCell (несвязанных с данными основной сетки)
00002: 'есть параллельное невидимое поле с настоящими связанными с данными значениями справочника
00003: 'Это иожно было бы утопить в класс в Combolib, но тогда это будет не DataGridView, a MyDataGridView
00004: Module ComboInGrid
00005:     Public Sub GridComboRefresh(ByVal PE As DS.PE, ByVal GR1 As Windows.Forms.DataGridView, _
00006:                                 ByVal g_ImProjectColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToProjectColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00007:                                 ByVal g_ImProgrammerColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToProgrammerColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00008:                                 ByVal g_ImStateColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToStateColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00009:                                 ByVal g_ImTypeColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToTypeColumn As Windows.Forms.DataGridViewTextBoxColumn)
00010:         With PE
00011:             For j As Integer = 0 To GR1.Rows.Count - 1
00012:                 For k As Integer = 0 To .PE_Project.Rows.Count - 1
00013:                     If .PE_Project(k).i = CInt(GR1.Rows(j).Cells(g_ToProjectColumn.Index).Value) Then
00014:                         CType(GR1.Rows(j).Cells(g_ImProjectColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = k
00015:                         CType(GR1.Rows(j).Cells(g_ImProjectColumn.Index), ComboLib.TypedDataGridViewCell).Value = .PE_Project(k).ProjectName
00016:                     End If
00017:                 Next
00018:                 For k As Integer = 0 To .PE_Prog.Rows.Count - 1
00019:                     If .PE_Prog(k).i = CInt(GR1.Rows(j).Cells(g_ToProgrammerColumn.Index).Value) Then
00020:                         CType(GR1.Rows(j).Cells(g_ImProgrammerColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = k
00021:                         CType(GR1.Rows(j).Cells(g_ImProgrammerColumn.Index), ComboLib.TypedDataGridViewCell).Value = .PE_Prog(k).ProgrammerName
00022:                     End If
00023:                 Next
00024:                 For k As Integer = 0 To .PE_State.Rows.Count - 1
00025:                     If .PE_State(k).i = CInt(GR1.Rows(j).Cells(g_ToStateColumn.Index).Value) Then
00026:                         CType(GR1.Rows(j).Cells(g_ImStateColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = k
00027:                         CType(GR1.Rows(j).Cells(g_ImStateColumn.Index), ComboLib.TypedDataGridViewCell).Value = .PE_State(k).StateName
00028:                     End If
00029:                 Next
00030:                 For k As Integer = 0 To .PE_Type.Rows.Count - 1
00031:                     If .PE_Type(k).i = CInt(GR1.Rows(j).Cells(g_ToTypeColumn.Index).Value) Then
00032:                         CType(GR1.Rows(j).Cells(g_ImTypeColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = k
00033:                         CType(GR1.Rows(j).Cells(g_ImTypeColumn.Index), ComboLib.TypedDataGridViewCell).Value = .PE_Type(k).ErrorName
00034:                     End If
00035:                 Next
00036:             Next
00037:         End With
00038:     End Sub
00039: 
00040:     Public Sub GridComboUpdate(ByVal GR1 As Windows.Forms.DataGridView, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs, ByVal DbKey As Integer, _
00041:                                ByVal g_ImProjectColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToProjectColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00042:                                ByVal g_ImProgrammerColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToProgrammerColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00043:                                ByVal g_ImStateColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToStateColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00044:                                ByVal g_ImTypeColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToTypeColumn As Windows.Forms.DataGridViewTextBoxColumn)
00045:         'это ключ в комбешнике - соответсвует ключу в связанной табле (загруженной в комбешники)
00046:         Dim NewImComboKey = CInt(CType(GR1.Rows(e.RowIndex).Cells(e.ColumnIndex), ComboLib.TypedDataGridViewCell).DataSetKey)
00047:         'это имя связанной таблы только для справки System.Windows.Forms.DataGridViewTextBoxCell
00048:         Dim RelatedTable = CType(GR1.Columns(e.ColumnIndex), ComboLib.TypedDataGridViewColumn).TableName
00049:         Select Case e.ColumnIndex
00050:             'редактировались комбешники 
00051:             Case g_ImProjectColumn.Index
00052:                 If CInt(GR1.Rows(e.RowIndex).Cells(g_ToProjectColumn.Index).Value) <> NewImComboKey Then
00053:                     GR1.Rows(e.RowIndex).Cells(g_ToProjectColumn.Index).Value = NewImComboKey
00054:                     SQL_UpdateIcon(DbKey, e.RowIndex, CInt(GR1.Rows(e.RowIndex).Cells(g_ToProjectColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToProgrammerColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToStateColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToTypeColumn.Index).Value))
00055:                 End If
00056:             Case g_ImProgrammerColumn.Index
00057:                 If CInt(GR1.Rows(e.RowIndex).Cells(g_ToProgrammerColumn.Index).Value) <> NewImComboKey Then
00058:                     GR1.Rows(e.RowIndex).Cells(g_ToProgrammerColumn.Index).Value = NewImComboKey
00059:                     SQL_UpdateIcon(DbKey, e.RowIndex, CInt(GR1.Rows(e.RowIndex).Cells(g_ToProjectColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToProgrammerColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToStateColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToTypeColumn.Index).Value))
00060: 
00061:                 End If
00062:             Case g_ImStateColumn.Index
00063:                 If CInt(GR1.Rows(e.RowIndex).Cells(g_ToStateColumn.Index).Value) <> NewImComboKey Then
00064:                     GR1.Rows(e.RowIndex).Cells(g_ToStateColumn.Index).Value = NewImComboKey
00065:                     SQL_UpdateIcon(DbKey, e.RowIndex, CInt(GR1.Rows(e.RowIndex).Cells(g_ToProjectColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToProgrammerColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToStateColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToTypeColumn.Index).Value))
00066:                 End If
00067:             Case g_ImTypeColumn.Index
00068:                 If CInt(GR1.Rows(e.RowIndex).Cells(g_ToTypeColumn.Index).Value) <> NewImComboKey Then
00069:                     GR1.Rows(e.RowIndex).Cells(g_ToTypeColumn.Index).Value = NewImComboKey
00070:                     SQL_UpdateIcon(DbKey, e.RowIndex, CInt(GR1.Rows(e.RowIndex).Cells(g_ToProjectColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToProgrammerColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToStateColumn.Index).Value), CInt(GR1.Rows(e.RowIndex).Cells(g_ToTypeColumn.Index).Value))
00071:                 End If
00072:         End Select
00073:     End Sub
00074: 
00075:     Public Sub GridComboNewRow(ByVal PE1 As DS.PE, ByVal IconBlock1 As ComboLib.IconBlock, ByVal NewGridRow As Windows.Forms.DataGridViewRow, _
00076:                                ByVal g_ImProjectColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToProjectColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00077:                                ByVal g_ImProgrammerColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToProgrammerColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00078:                                ByVal g_ImStateColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToStateColumn As Windows.Forms.DataGridViewTextBoxColumn, _
00079:                                ByVal g_ImTypeColumn As ComboLib.TypedDataGridViewColumn, ByVal g_ToTypeColumn As Windows.Forms.DataGridViewTextBoxColumn)
00080: 
00081:         If IconBlock1.CurProjIcon Is Nothing Then
00082:             NewGridRow.Cells(g_ToProjectColumn.Index).Value = PE1.PE_Project(0).i
00083:             CType(NewGridRow.Cells(g_ImProjectColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_Project(0).ProjectName
00084:             CType(NewGridRow.Cells(g_ImProjectColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = 0
00085:         Else
00086:             NewGridRow.Cells(g_ToProjectColumn.Index).Value = IconBlock1.CurProjKey
00087:             For j As Integer = 0 To PE1.PE_Project.Rows.Count - 1
00088:                 If PE1.PE_Project(j).i = IconBlock1.CurProjKey Then
00089:                     CType(NewGridRow.Cells(g_ImProjectColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_Project(j).ProjectName
00090:                     CType(NewGridRow.Cells(g_ImProjectColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = j
00091:                 End If
00092:             Next
00093:         End If
00094:         If IconBlock1.CurProgIcon Is Nothing Then
00095:             NewGridRow.Cells(g_ToProgrammerColumn.Index).Value = PE1.PE_Prog(0).i
00096:             CType(NewGridRow.Cells(g_ImProgrammerColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_Prog(0).ProgrammerName
00097:             CType(NewGridRow.Cells(g_ImProgrammerColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = 0
00098:         Else
00099:             NewGridRow.Cells(g_ToProgrammerColumn.Index).Value = IconBlock1.CurProgKey
00100:             For j As Integer = 0 To PE1.PE_Prog.Rows.Count - 1
00101:                 If PE1.PE_Prog(j).i = IconBlock1.CurProgKey Then
00102:                     CType(NewGridRow.Cells(g_ImProgrammerColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_Prog(j).ProgrammerName
00103:                     CType(NewGridRow.Cells(g_ImProgrammerColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = j
00104:                 End If
00105:             Next
00106:         End If
00107:         If IconBlock1.CurStateIcon Is Nothing Then
00108:             NewGridRow.Cells(g_ToStateColumn.Index).Value = PE1.PE_State(0).i
00109:             CType(NewGridRow.Cells(g_ImStateColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_State(0).StateName
00110:             CType(NewGridRow.Cells(g_ImStateColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = 0
00111:         Else
00112:             NewGridRow.Cells(g_ToStateColumn.Index).Value = IconBlock1.CurStateKey
00113:             For j As Integer = 0 To PE1.PE_State.Rows.Count - 1
00114:                 If PE1.PE_State(j).i = IconBlock1.CurStateKey Then
00115:                     CType(NewGridRow.Cells(g_ImStateColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_State(j).StateName
00116:                     CType(NewGridRow.Cells(g_ImStateColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = j
00117:                 End If
00118:             Next
00119:         End If
00120:         If IconBlock1.CurTypeIcon Is Nothing Then
00121:             NewGridRow.Cells(g_ToTypeColumn.Index).Value = PE1.PE_Type(0).i
00122:             CType(NewGridRow.Cells(g_ImTypeColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_Type(0).ErrorName
00123:             CType(NewGridRow.Cells(g_ImTypeColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = 0
00124:         Else
00125:             NewGridRow.Cells(g_ToTypeColumn.Index).Value = IconBlock1.CurTypeKey
00126:             For j As Integer = 0 To PE1.PE_Type.Rows.Count - 1
00127:                 If PE1.PE_Type(j).i = IconBlock1.CurTypeKey Then
00128:                     CType(NewGridRow.Cells(g_ImTypeColumn.Index), ComboLib.TypedDataGridViewCell).Value = PE1.PE_Type(j).ErrorName
00129:                     CType(NewGridRow.Cells(g_ImTypeColumn.Index), ComboLib.TypedDataGridViewCell).SelectedIndex = j
00130:                 End If
00131:             Next
00132:         End If
00133:     End Sub
00134: 
00135: End Module


Комментарии к этой страничке ( )
ссылка на эту страничку: http://www.vb-net.ru/wanted/my/imagecombo.htm
<Назад>  <Назад>  <Назад>  <На главную>  <В раздел ASP>  <В раздел NET>  <В раздел SQL>  <В раздел Разное>  <Написать автору>  < Поблагодарить>