Типизируемый тип столбца в 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 '<DebuggerStepThrough()> _ 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
<SITEMAP> <MVC> <ASP> <NET> <DATA> <KIOSK> <FLEX> <SQL> <NOTES> <LINUX> <MONO> <FREEWARE> <DOCS> <ENG> <CHAT ME> <ABOUT ME> < THANKS ME> |