|
I'd like to nest a datagrid view insidea column of another datagridview. Is this possible using the standard functionality exposed by Visual Basic 2008 Express?
If not, is anyone aware of any free third party control that implements this functionality? I know both infragistics and devexpress have such controls, but they're bundled with a load of other stuff that I don't need, and they don't come cheap.
I can nest html tablesand load them into my form using a webbrowser control, but that wouldn't serve my other purpose, which is, I want the users to be able to navigate through the rows one at a time using the up and down arrow keys (not between rows of the inner nested table, only between the outer table's rows),which is not possible using html tables. Anyone have any good ideas? | | reachrishikh Tuesday, February 03, 2009 9:49 AM | Hi Reachrishikh,
> 1) Get the datagrid control to show up in my toolbox in Visual Basic 2008 Express.
Right click on Toolbox and select "Choose Items". In the Choose Toolbox Items dialog, switch to the .NET Framework Components tab. In the Filter textbox type "DataGrid" and then select the checkbox before DataGrid in the Global Assembly Cache. Click OK to close this dialog and the DataGrid control is added to Toolbox.
> 2) And if it really isn't much of a hassle, then how do you nest the two datagrids within one another?
I haven't heard that we can nesta DataGrid within another DataGrid. But it's true that DataGrid can show parent/child tables at the same time.
The key points of hosting a custom control in DataGridView cells are as follows: 1. Implemen the IDataGridViewEditingControl interface on the custom control to get it ready to be hosted. Through implementing the IDataGridViewEditingControl, the custom control knows how to get cell value and initialize itself and pass the value back to the cell. 2. Create a new type DataGridView cell to host the custom control. 3. Create a new type DataGridView column to contain the above custom DataGridView cell.
If you want a sample on how to host a DataGridView to DataGridView cell, I can send you. Please send an email to v-lliu@microsoft.com to let me know your email address and then I can send it to you.
Sincerely, Linda Liu
- Marked As Answer byreachrishikh Saturday, March 07, 2009 5:04 PM
-
| | Linda Liu Thursday, February 19, 2009 10:08 AM | Hi Reachrishikh,
Actually, the "bug" you mentioned in my sample project is by design : ) I just take it as an example to regard the row count of the hosted DataGridView as the value of the derived DataGridViewColumn. You need to modify it to meet your requirement.
> I want it to return the contents of the nested grid as a grid.
You need to draw the grid in the cell by yourself. To do this, change the base type of the NestedDGVCell to DataGridViewCell and override the Paint method to draw the nested grid.
The following is a sample:
| PublicClassNestedDgvCell |
| InheritsDataGridViewCell |
|
| PrivatedgvAsNewDataGridView |
|
| PrivateSubSetupDGVToDraw() |
| IfTypeOf(Value)IsDataTableThen |
| dgv.Columns.Clear() |
| ForEachcolumnAsDataColumnInCType(Value,DataTable).Columns |
| dgv.Columns.Add(column.ColumnName,column.ColumnName) |
| Next |
| ForEachdatarowAsDataRowInCType(Value,DataTable).Rows |
| dgv.Rows.Add(datarow.ItemArray) |
| Next |
| EndIf |
| EndSub |
|
| ProtectedOverridesSubPaint(ByValgraphicsAsSystem.Drawing.Graphics,ByValclipBoundsAsSystem.Drawing.Rectangle,ByValcellBoundsAsSystem.Drawing.Rectangle,ByValrowIndexAsInteger,ByValcellStateAsSystem.Windows.Forms.DataGridViewElementStates,ByValvalueAsObject,ByValformattedValueAsObject,ByValerrorTextAsString,ByValcellStyleAsSystem.Windows.Forms.DataGridViewCellStyle,ByValadvancedBorderStyleAsSystem.Windows.Forms.DataGridViewAdvancedBorderStyle,ByValpaintPartsAsSystem.Windows.Forms.DataGridViewPaintParts) |
| MyBase.Paint(graphics,clipBounds,cellBounds,rowIndex,cellState,value,formattedValue,errorText,cellStyle,advancedBorderStyle,paintParts) |
| graphics.FillRectangle(NewSolidBrush(cellStyle.BackColor),cellBounds) |
|
| SetupDGVToDraw() |
| DimabbreviationAsNewBitmap(cellBounds.Width,cellBounds.Height) |
| dgv.DrawToBitmap(abbreviation,NewRectangle(0,0,cellBounds.Width,cellBounds.Height)) |
| graphics.DrawImage(abbreviation,cellBounds,NewRectangle(0,0,abbreviation.Width,abbreviation.Height),GraphicsUnit.Pixel) |
|
|
| EndSub |
| PublicOverridesSubInitializeEditingControl(ByValrowIndexAsInteger,_ |
| ByValinitialFormattedValueAsObject,_ |
| ByValdataGridViewCellStyleAsDataGridViewCellStyle) |
|
| 'Setthevalueoftheeditingcontroltothecurrentcellvalue. |
| MyBase.InitializeEditingControl(rowIndex,initialFormattedValue,_ |
| dataGridViewCellStyle) |
| EndSub |
|
| PublicOverridesReadOnlyPropertyEditType()AsType |
| Get |
| 'ReturnthetypeoftheeditingcontolthatDgvCelluses. |
| ReturnGetType(DgvEditingControl) |
| EndGet |
| EndProperty |
|
| PublicOverridesPropertyValueType()AsSystem.Type |
| Get |
| ReturnGetType(Object) |
| EndGet |
| Set(ByValvalueAsSystem.Type) |
| |
| EndSet |
| EndProperty |
|
| EndClass | Hope this helps. If you have any question, please feel free to let me know. Sincerely, Linda Liu - Marked As Answer byreachrishikh Saturday, March 07, 2009 5:05 PM
-
| | Linda Liu Tuesday, February 24, 2009 9:24 AM | You have to create a custom DataGridViewColumn class. Keep in mind that DataGridView doesn't support nesting details / parent-child relationships per row. I haven't seen one which can host a DataGridView in a column, but it's possible. Have a look here: http://msdn.microsoft.com/en-us/library/aa730882.aspxThis is an example on how to implement custom columns for radio buttons. The rest is up to you. regards, franking - Edited byfranking Tuesday, February 03, 2009 11:36 AMtypo
-
| | franking Tuesday, February 03, 2009 11:35 AM | Hi Reachrishikh,
I don't know why you want to nest a DataGridView inside another DataGridView, but it's possible to host any control to DataGridView cells.
See the following sample to get started: http://msdn.microsoft.com/en-us/library/7tas5c80(VS.80).aspx
Hope this helps.
If you have any question, please feel free to let us know.
Sincerely, Linda Liu - Unmarked As Answer byreachrishikh Friday, February 06, 2009 10:00 AM
- Marked As Answer byLinda LiuMSFT, ModeratorFriday, February 06, 2009 6:13 AM
-
| | Linda Liu Thursday, February 05, 2009 9:03 AM | Hey thanks. I've been looking through the link Franking posted as well. Yours looks like a more direct approach.Will try all these out to see what works. Thanks again. | | reachrishikh Thursday, February 05, 2009 9:07 AM | I'm at a loss! I'm not much good with user-interface design.
I tried my best to mofify the code in the link posted by Linda Liu to reflect the datagridview control instead of datetimepicker, but so far, I have absolutelyno idea what I have done.
| 1 |
ImportsSystem |
| 2 |
ImportsSystem.Windows.Forms |
| 3 |
|
| 4 |
PublicClassNestedDgvColumn |
| 5 |
InheritsDataGridViewColumn |
| 6 |
|
| 7 |
PublicSubNew() |
| 8 |
MyBase.New(NewNestedDgvCell()) |
| 9 |
EndSub |
| 10 |
|
| 11 |
|
| 12 |
PublicOverridesPropertyCellTemplate()AsDataGridViewCell |
| 13 |
Get |
| 14 |
ReturnMyBase.CellTemplate |
| 15 |
EndGet |
| 16 |
Set(ByValvalueAsDataGridViewCell) |
| 17 |
|
| 18 |
'EnsurethatthecellusedforthetemplateisaDataGridViewCell. |
| 19 |
If(valueIsNotNothing)AndAlso_ |
| 20 |
Notvalue.GetType().IsAssignableFrom(GetType(NestedDgvCell))_ |
| 21 |
Then |
| 22 |
ThrowNewInvalidCastException("MustbeaNestedDgvCell") |
| 23 |
EndIf |
| 24 |
MyBase.CellTemplate=value |
| 25 |
|
| 26 |
EndSet |
| 27 |
EndProperty |
| 28 |
EndClass |
| 29 |
|
| 30 |
PublicClassNestedDgvCell |
| 31 |
InheritsDataGridViewCell |
| 32 |
|
| 33 |
PublicOverridesSubInitializeEditingControl(ByValrowIndexAsInteger,_ |
| 34 |
ByValinitialFormattedValueAsObject,_ |
| 35 |
ByValdataGridViewCellStyleAsDataGridViewCellStyle) |
| 36 |
|
| 37 |
'Setthevalueoftheeditingcontroltothecurrentcellvalue. |
| 38 |
MyBase.InitializeEditingControl(rowIndex,initialFormattedValue,_ |
| 39 |
dataGridViewCellStyle) |
| 40 |
|
| 41 |
EndSub |
| 42 |
|
| 43 |
PublicOverridesReadOnlyPropertyEditType()AsType |
| 44 |
Get |
| 45 |
'ReturnthetypeoftheeditingcontolthatDgvCelluses. |
| 46 |
ReturnGetType(DgvEditingControl) |
| 47 |
EndGet |
| 48 |
EndProperty |
| 49 |
|
| 50 |
PublicOverridesReadOnlyPropertyValueType()AsType |
| 51 |
Get |
| 52 |
'ReturnthetypeofthevaluethatDgvCellcontains. |
| 53 |
ReturnGetType(String) |
| 54 |
EndGet |
| 55 |
EndProperty |
| 56 |
|
| 57 |
EndClass |
| 58 |
|
| 59 |
ClassDgvEditingControl |
| 60 |
InheritsDataGridView |
| 61 |
ImplementsIDataGridViewEditingControl |
| 62 |
|
| 63 |
PublicPropertyEditingControlRowIndex()AsInteger_ |
| 64 |
ImplementsIDataGridViewEditingControl.EditingControlRowIndex |
| 65 |
|
| 66 |
Get |
| 67 |
ReturnrowIndexNum |
| 68 |
EndGet |
| 69 |
Set(ByValvalueAsInteger) |
| 70 |
rowIndexNum=value |
| 71 |
EndSet |
| 72 |
|
| 73 |
EndProperty |
| 74 |
|
| 75 |
EndClass |
Am I on the right track, or should I give up the idea of trying to code it myself, and start looking for third-party controls that do this thing?
Infact, I just realised, I don't even need to have a custom datagridview column in the form of another datagridview. Since any control can be hosted in datagridview cells, I can even solve my problem by using a listbox.
If putting in a datagridview inside a datagridview cell is too much of a hassle, could someone please help me with putting in a listbox instead? Would be really grateful. - Edited byreachrishikh Thursday, February 12, 2009 1:14 PMadded line numbers to code
-
| | reachrishikh Thursday, February 05, 2009 10:42 AM | Hi Reachrishikh,
You're on the right track to embed a DataGridView to another DataGridView cells. I assume your problem so far is that you don't "see" a nested DataGridView shows in a cell whenthis cellis in edit mode. In fact, the nested DataGridView is shown in the cell, but it has no columns in it so it seems as if it is not shown.
In the override InitializeEditingControl method within the NestedDgvCell class, add some columns in the hosted editing control, i.e. DataGridView. For example:
Public Class NestedDgvCell Inherits DataGridViewTextBoxCell
Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, _ ByVal initialFormattedValue As Object, _ ByVal dataGridViewCellStyle As DataGridViewCellStyle)
' Set the value of the editing control to the current cell value. MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, _ dataGridViewCellStyle)
' add some columns to the hosted DataGridView Dim ctrl As DataGridView = DataGridView.EditingControl If ctrl.Columns.Count = 0 Then ctrl.Columns.Add("column1", "column 1") ctrl.Columns.Add("column2", "column 2") End If
End Sub
...
End Class
You can use the same way to host a ListBox in DataGridView cells.
Hope this helps. If you have any question, please feel free to let me know.
Sincerely, Linda Liu | | Linda Liu Friday, February 06, 2009 6:13 AM | Hi, Sorry for not responding to this before, I was caught up in another issue.
Anyway, I don't think I'm on the right track for this thing, even though you assure me otherwise. For one, I have blue squiggly lines under several places in the code, and I have no idea how to fix them.
1) At line 61, there is a blue squiggly below IDataGridViewEditingControl and it says Class 'DgvEditingControl' must implement 'ReadOnly Property RepositionEditingControlOnValueChange() As Boolean' for interface 'System.Windows.Forms.IDataGridViewEditingControl'. Implementing property must have matching 'ReadOnly' or 'WriteOnly' specifiers.
2) At line 50, there is a blue squiggly below ValueType and it says 'Public Overrides ReadOnly Property ValueType() As System.Type' cannot override 'Public Overridable Property ValueType() As System.Type' because they differ by 'ReadOnly' or 'WriteOnly'.
| | reachrishikh Thursday, February 12, 2009 1:25 PM | Hi Reachrishikh,
There're several methods in the IDataGridViewEditingControl interface that you must implement. What you can do is to follow the indication VS gives you to "fix" the problem. You can refer to the sample I provided in my first replyto implement the IDataGridViewEditingControl interface in your application.
If you have any question, please feel free to let me know.
Sincerely, Linda Liu | | Linda Liu Friday, February 13, 2009 10:29 AM | Hi, I told you, I'm totally in the blind here, this isn't familiar territory, I'm blindly copying and pasting code without having a clue as to what I'm doing. I really don't know how to solve those issues I mentioned I'm having, not with the help of the sample either. Otherwise I wouldn't have posted here.
I tried adding the line Implements RepositionEditingControlOnValueChange before the line Implements IDataGridViewEditingControl in order to solve the first issue, but it still gives me another blue squiggly line.
A little more detailed help will be greatly appreciated.
I've heard that it's easier to nest grids in the datagrid control rather than with the datagridview control. Could you please tell me how to 1) Get the datagrid control to show up in my toolbox in Visual Basic 2008 Express. 2) And if it really isn't much of a hassle, then how do you nest the two datagrids within one another? | | reachrishikh Monday, February 16, 2009 3:29 PM | Hi Reachrishikh,
> 1) Get the datagrid control to show up in my toolbox in Visual Basic 2008 Express.
Right click on Toolbox and select "Choose Items". In the Choose Toolbox Items dialog, switch to the .NET Framework Components tab. In the Filter textbox type "DataGrid" and then select the checkbox before DataGrid in the Global Assembly Cache. Click OK to close this dialog and the DataGrid control is added to Toolbox.
> 2) And if it really isn't much of a hassle, then how do you nest the two datagrids within one another?
I haven't heard that we can nesta DataGrid within another DataGrid. But it's true that DataGrid can show parent/child tables at the same time.
The key points of hosting a custom control in DataGridView cells are as follows: 1. Implemen the IDataGridViewEditingControl interface on the custom control to get it ready to be hosted. Through implementing the IDataGridViewEditingControl, the custom control knows how to get cell value and initialize itself and pass the value back to the cell. 2. Create a new type DataGridView cell to host the custom control. 3. Create a new type DataGridView column to contain the above custom DataGridView cell.
If you want a sample on how to host a DataGridView to DataGridView cell, I can send you. Please send an email to v-lliu@microsoft.com to let me know your email address and then I can send it to you.
Sincerely, Linda Liu
- Marked As Answer byreachrishikh Saturday, March 07, 2009 5:04 PM
-
| | Linda Liu Thursday, February 19, 2009 10:08 AM | Email sent. | | reachrishikh Sunday, February 22, 2009 12:38 PM | Thank you for that sample.
I tried running it, but it seems to have a bug. If you try to enter a value in the column(s) of the childdatagridview column and then move to the other column in the parent datagridview, the values in the child datagridview column disappear, and it shows a string - "2". If you try to enter the child datagridview again, your entered values have disappeared. | | reachrishikh Monday, February 23, 2009 11:06 AM | Allright, I think I solved that bug by removing this code - ctrl.Rows.Clear()
Actually I removed this entire code since I'll be populating the nested datagridview as well as its parent from a datatable extracted from a sql query. The user won't be entering or modifying any values held in the nesteddatagridview or its parent datagridview at all.
| 1 |
'addsomecolumnstothehostedDataGridView |
| 2 |
DimctrlAsDataGridView=DataGridView.EditingControl |
| 3 |
Ifctrl.Columns.Count=0Then |
| 4 |
ctrl.Columns.Add("column1","column1") |
| 5 |
ctrl.Columns.Add("column2","column2") |
| 6 |
EndIf |
| 7 |
'ctrl.Rows.Clear() |
| 8 |
IfNotinitialFormattedValue.Equals("")Then |
| 9 |
ctrl.RowCount=Convert.ToInt32(initialFormattedValue) |
| 10 |
EndIf |
Okay, there's one more thing. The nesteddatagridview is returning the number of rows it contains as an integer in theparent datagridview column. I want it to return the contents of the nested grid as a grid. This only happens when you enter the nested grid in edit mode and reverts back to showing the rowcount integer when you exit the edit mode. How do I fix this?
| | reachrishikh Monday, February 23, 2009 1:19 PM | Hi Reachrishikh,
Actually, the "bug" you mentioned in my sample project is by design : ) I just take it as an example to regard the row count of the hosted DataGridView as the value of the derived DataGridViewColumn. You need to modify it to meet your requirement.
> I want it to return the contents of the nested grid as a grid.
You need to draw the grid in the cell by yourself. To do this, change the base type of the NestedDGVCell to DataGridViewCell and override the Paint method to draw the nested grid.
The following is a sample:
| PublicClassNestedDgvCell |
| InheritsDataGridViewCell |
|
| PrivatedgvAsNewDataGridView |
|
| PrivateSubSetupDGVToDraw() |
| IfTypeOf(Value)IsDataTableThen |
| dgv.Columns.Clear() |
| ForEachcolumnAsDataColumnInCType(Value,DataTable).Columns |
| dgv.Columns.Add(column.ColumnName,column.ColumnName) |
| Next |
| ForEachdatarowAsDataRowInCType(Value,DataTable).Rows |
| dgv.Rows.Add(datarow.ItemArray) |
| Next |
| EndIf |
| EndSub |
|
| ProtectedOverridesSubPaint(ByValgraphicsAsSystem.Drawing.Graphics,ByValclipBoundsAsSystem.Drawing.Rectangle,ByValcellBoundsAsSystem.Drawing.Rectangle,ByValrowIndexAsInteger,ByValcellStateAsSystem.Windows.Forms.DataGridViewElementStates,ByValvalueAsObject,ByValformattedValueAsObject,ByValerrorTextAsString,ByValcellStyleAsSystem.Windows.Forms.DataGridViewCellStyle,ByValadvancedBorderStyleAsSystem.Windows.Forms.DataGridViewAdvancedBorderStyle,ByValpaintPartsAsSystem.Windows.Forms.DataGridViewPaintParts) |
| MyBase.Paint(graphics,clipBounds,cellBounds,rowIndex,cellState,value,formattedValue,errorText,cellStyle,advancedBorderStyle,paintParts) |
| graphics.FillRectangle(NewSolidBrush(cellStyle.BackColor),cellBounds) |
|
| SetupDGVToDraw() |
| DimabbreviationAsNewBitmap(cellBounds.Width,cellBounds.Height) |
| dgv.DrawToBitmap(abbreviation,NewRectangle(0,0,cellBounds.Width,cellBounds.Height)) |
| graphics.DrawImage(abbreviation,cellBounds,NewRectangle(0,0,abbreviation.Width,abbreviation.Height),GraphicsUnit.Pixel) |
|
|
| EndSub |
| PublicOverridesSubInitializeEditingControl(ByValrowIndexAsInteger,_ |
| ByValinitialFormattedValueAsObject,_ |
| ByValdataGridViewCellStyleAsDataGridViewCellStyle) |
|
| 'Setthevalueoftheeditingcontroltothecurrentcellvalue. |
| MyBase.InitializeEditingControl(rowIndex,initialFormattedValue,_ |
| dataGridViewCellStyle) |
| EndSub |
|
| PublicOverridesReadOnlyPropertyEditType()AsType |
| Get |
| 'ReturnthetypeoftheeditingcontolthatDgvCelluses. |
| ReturnGetType(DgvEditingControl) |
| EndGet |
| EndProperty |
|
| PublicOverridesPropertyValueType()AsSystem.Type |
| Get |
| ReturnGetType(Object) |
| EndGet |
| Set(ByValvalueAsSystem.Type) |
| |
| EndSet |
| EndProperty |
|
| EndClass | Hope this helps. If you have any question, please feel free to let me know. Sincerely, Linda Liu - Marked As Answer byreachrishikh Saturday, March 07, 2009 5:05 PM
-
| | Linda Liu Tuesday, February 24, 2009 9:24 AM | Should I be putting in some other value in place of"(Value)"in this line: If TypeOf (Value) Is DataTable Then
because when I run it, it gives me the following error on this line - "Specified argument was out of the range of valid values. Parameter name: rowIndex" I have set up a datatable in the NestedDgvCell class as under:
| 1 |
PublicClassNestedDgvCell |
| 2 |
InheritsDataGridViewCell |
| 3 |
|
| 4 |
PrivatedgvAsNewDataGridView |
| 5 |
DimdtAsNewDataTable() |
| 6 |
|
| 7 |
PublicSubNew() |
| 8 |
SetupDataTable() |
| 9 |
EndSub |
| 10 |
|
| 11 |
SubSetupDataTable() |
| 12 |
dt.Columns.Add("Column1") |
| 13 |
dt.Columns.Add("Column2") |
| 14 |
dt.Columns.Add("Column3") |
| 15 |
EndSub |
Now how do I connect this datatable to the subprocedure SetupDGVToDraw? | | reachrishikh Wednesday, February 25, 2009 1:29 PM | Hi Reachrishikh,
When Irun my application,I don't get the error you mentioned. > Now how do I connect this datatable to the subprocedure SetupDGVToDraw?
The DataTable should be created outside of the DataGridView. You just need to assign the DataTable to the Value property of the NestedDGVCell.
I send the modified sample project to your mail box. The sample application runs fine on my side. If you have any question, please feel freeto let me know.
Sincerely, Linda Liu | | Linda Liu Tuesday, March 03, 2009 11:22 AM | Thanks, that makes a lot of sense now. I was setting the datasourcepropertyof the nested datagridview so far, instead of setting the value property.
Okay, it's working. But if I set the value property of the nested datagridview to a datatable, then I can't populate my outside datagridviewby setting its datasource toa second datatable. It gives me the error again on the same line of code: If TypeOf (Value) Is DataTable Then "Specified argument was out of the range of valid values. Parameter name: rowIndex" | | reachrishikh Wednesday, March 04, 2009 10:46 AM | Hi Reachrishikh,
I have modified the sample project to bind the DataGridView to a data source. It woks well on my side. I send the modified sample project to your mail box.
Thanks, Linda Liu | | Linda Liu Friday, March 06, 2009 10:57 AM | Thanks a lot Linda Liu. I'm now using a list to populate the outer table instead of a datatable, like you suggested in the emailed project, and everything is finally working fine now!
I now have a fully functional nested datagridview, thanks solely to your help. Thank you very much. You don't know how many people, not just me, you have helped by providing this solution. In searching for a nested datagridview, I came across many people like me who are looking for the same thing.
I am not going to take any credit for this datagridview column, this is all you.
I think you should put it up somewhere like sourceforge, that way it could help a lot more people.
I have another question, although this is largely cosmetic. We are setting the columns in the nesteddatagridview here:
If TypeOf (Value) Is DataTable Then dgv.Columns.Clear() For Each column As DataColumn In CType(Value, DataTable).Columns dgv.Columns.Add(column.ColumnName, column.ColumnName) Next ..... End If
So here we can only set the column name and header text for the column. How do I set other properties for the columns created here such as the width, and defaultcellstyle.format?
| | reachrishikh Saturday, March 07, 2009 5:03 PM | This is the entire code to implement a nested datagridview functionality. Code courtesyof Linda Liu, I'm not going to steal her credit.
| 1 |
PublicClassNestedDgvColumn |
| 2 |
InheritsDataGridViewColumn |
| 3 |
|
| 4 |
PublicSubNew() |
| 5 |
MyBase.New(NewNestedDgvCell()) |
| 6 |
EndSub |
| 7 |
|
| 8 |
PublicOverridesPropertyCellTemplate()AsDataGridViewCell |
| 9 |
Get |
| 10 |
ReturnMyBase.CellTemplate |
| 11 |
EndGet |
| 12 |
Set(ByValvalueAsDataGridViewCell) |
| 13 |
|
| 14 |
'EnsurethatthecellusedforthetemplateisaDataGridViewCell. |
| 15 |
If(valueIsNotNothing)AndAlso_ |
| 16 |
Notvalue.GetType().IsAssignableFrom(GetType(NestedDgvCell))_ |
| 17 |
Then |
| 18 |
ThrowNewInvalidCastException("MustbeaNestedDgvCell") |
| 19 |
EndIf |
| 20 |
MyBase.CellTemplate=value |
| 21 |
|
| 22 |
EndSet |
| 23 |
EndProperty |
| 24 |
EndClass |
| 25 |
|
| 26 |
PublicClassNestedDgvCell |
| 27 |
InheritsDataGridViewCell |
| 28 |
|
| 29 |
PrivatedgvAsNewDataGridView |
| 30 |
|
| 31 |
PrivateSubSetupDGVToDraw() |
| 32 |
|
| 33 |
'reachrishikhedit |
| 34 |
'ifyou'relikemeandwanttomodifythelooksofyournesteddatagridview, |
| 35 |
'youcanusethecodeasbelow. |
| 36 |
dgv.BackgroundColor=SystemColors.Control |
| 37 |
dgv.Size=NewSize(400,100) |
| 38 |
dgv.AllowUserToAddRows=False |
| 39 |
dgv.RowHeadersVisible=False |
| 40 |
dgv.ColumnHeadersVisible=False |
| 41 |
dgv.SelectionMode=DataGridViewSelectionMode.FullRowSelect |
| 42 |
dgv.BorderStyle=Windows.Forms.BorderStyle.None |
| 43 |
dgv.AutoGenerateColumns=False |
| 44 |
'endreachrishikhedit |
| 45 |
|
| 46 |
IfTypeOf(Value)IsDataTableThen |
| 47 |
'reachrishikhedit |
| 48 |
'ifyousimplywanttoaddcolumnstothenesteddatagridviewaspertheschema |
| 49 |
'ofthedatatableyou'rebindingtoit,thenusethecodebelow |
| 50 |
'dgv.Columns.Clear() |
| 51 |
'ForEachcolumnAsDataColumnInCType(Value,DataTable).Columns |
| 52 |
'dgv.Columns.Add(column.ColumnName,column.ColumnName) |
| 53 |
'Next |
| 54 |
'endreachrishikhedit |
| 55 |
|
| 56 |
'reachrishikhedit |
| 57 |
'elseusethiscodeifyouwanttocustomformatyourcolumns |
| 58 |
DimtableAsDataTable=DirectCast(Value,DataTable) |
| 59 |
dgv.Columns.Clear() |
| 60 |
DimdgvColumnAsDataGridViewTextBoxColumn |
| 61 |
ForEachcolumnAsDataColumnIntable.Columns |
| 62 |
dgvColumn=NewDataGridViewTextBoxColumn |
| 63 |
dgvColumn.Name=column.ColumnName |
| 64 |
dgvColumn.HeaderText=column.ColumnName |
| 65 |
dgvColumn.DefaultCellStyle.Format="C2" |
| 66 |
dgvColumn.ValueType=GetType(Decimal) |
| 67 |
dgv.Columns.Add(dgvColumn) |
| 68 |
Next |
| 69 |
'endreachrishikhedit |
| 70 |
|
| 71 |
ForEachdatarowAsDataRowInCType(Value,DataTable).Rows |
| 72 |
dgv.Rows.Add(datarow.ItemArray) |
| 73 |
Next |
| 74 |
EndIf |
| 75 |
|
| 76 |
EndSub |
| 77 |
|
| 78 |
ProtectedOverridesSubPaint(ByValgraphicsAsSystem.Drawing.Graphics,ByValclipBoundsAsSystem.Drawing.Rectangle,ByValcellBoundsAsSystem.Drawing.Rectangle,ByValrowIndexAsInteger,ByValcellStateAsSystem.Windows.Forms.DataGridViewElementStates,ByValvalueAsObject,ByValformattedValueAsObject,ByValerrorTextAsString,ByValcellStyleAsSystem.Windows.Forms.DataGridViewCellStyle,ByValadvancedBorderStyleAsSystem.Windows.Forms.DataGridViewAdvancedBorderStyle,ByValpaintPartsAsSystem.Windows.Forms.DataGridViewPaintParts) |
| 79 |
MyBase.Paint(graphics,clipBounds,cellBounds,rowIndex,cellState,value,formattedValue,errorText,cellStyle,advancedBorderStyle,paintParts) |
| 80 |
graphics.FillRectangle(NewSolidBrush(cellStyle.BackColor),cellBounds) |
| 81 |
|
| 82 |
SetupDGVToDraw() |
| 83 |
DimabbreviationAsNewBitmap(cellBounds.Width,cellBounds.Height) |
| 84 |
dgv.DrawToBitmap(abbreviation,NewRectangle(0,0,cellBounds.Width,cellBounds.Height)) |
| 85 |
graphics.DrawImage(abbreviation,cellBounds,NewRectangle(0,0,abbreviation.Width,abbreviation.Height),GraphicsUnit.Pixel) |
| 86 |
EndSub |
| 87 |
|
| 88 |
PublicOverridesSubInitializeEditingControl(ByValrowIndexAsInteger,_ |
| 89 |
ByValinitialFormattedValueAsObject,_ |
| 90 |
ByValdataGridViewCellStyleAsDataGridViewCellStyle) |
| 91 |
|
| 92 |
'Setthevalueoftheeditingcontroltothecurrentcellvalue. |
| 93 |
MyBase.InitializeEditingControl(rowIndex,initialFormattedValue,_ |
| 94 |
dataGridViewCellStyle) |
| 95 |
EndSub |
| 96 |
|
| 97 |
PublicOverridesReadOnlyPropertyEditType()AsType |
| 98 |
Get |
| 99 |
'ReturnthetypeoftheeditingcontolthatDgvCelluses. |
| 100 |
ReturnGetType(DgvEditingControl) |
| 101 |
EndGet |
| 102 |
EndProperty |
| 103 |
|
| 104 |
PublicOverridesPropertyValueType()AsSystem.Type |
| 105 |
Get |
| 106 |
ReturnGetType(Object) |
| 107 |
EndGet |
| 108 |
Set(ByValvalueAsSystem.Type) |
| 109 |
|
| 110 |
EndSet |
| 111 |
EndProperty |
| 112 |
|
| 113 |
EndClass |
| 114 |
|
| 115 |
ClassDgvEditingControl |
| 116 |
InheritsDataGridView |
| 117 |
ImplementsIDataGridViewEditingControl |
| 118 |
|
| 119 |
PrivatedataGridViewControlAsDataGridView |
| 120 |
PrivatevalueIsChangedAsBoolean=False |
| 121 |
PrivaterowIndexNumAsInteger |
| 122 |
|
| 123 |
PublicPropertyEditingControlFormattedValue()AsObject_ |
| 124 |
ImplementsIDataGridViewEditingControl.EditingControlFormattedValue |
| 125 |
|
| 126 |
Get |
| 127 |
ReturnMe.RowCount |
| 128 |
EndGet |
| 129 |
|
| 130 |
Set(ByValvalueAsObject) |
| 131 |
'IfTypeOfvalueIsStringThen |
| 132 |
'Me.RowCount=Convert.ToInt32(value) |
| 133 |
'EndIf |
| 134 |
EndSet |
| 135 |
|
| 136 |
EndProperty |
| 137 |
|
| 138 |
PublicFunctionGetEditingControlFormattedValue(ByValcontext_ |
| 139 |
AsDataGridViewDataErrorContexts)AsObject_ |
| 140 |
ImplementsIDataGridViewEditingControl.GetEditingControlFormattedValue |
| 141 |
|
| 142 |
ReturnMe.RowCount |
| 143 |
|
| 144 |
EndFunction |
| 145 |
|
| 146 |
PublicSubApplyCellStyleToEditingControl(ByValdataGridViewCellStyleAs_ |
| 147 |
DataGridViewCellStyle)_ |
| 148 |
ImplementsIDataGridViewEditingControl.ApplyCellStyleToEditingControl |
| 149 |
|
| 150 |
Me.Font=dataGridViewCellStyle.Font |
| 151 |
Me.ForeColor=dataGridViewCellStyle.ForeColor |
| 152 |
Me.BackgroundColor=dataGridViewCellStyle.BackColor |
| 153 |
EndSub |
| 154 |
|
| 155 |
PublicPropertyEditingControlRowIndex()AsInteger_ |
| 156 |
ImplementsIDataGridViewEditingControl.EditingControlRowIndex |
| 157 |
|
| 158 |
Get |
| 159 |
ReturnrowIndexNum |
| 160 |
EndGet |
| 161 |
Set(ByValvalueAsInteger) |
| 162 |
rowIndexNum=value |
| 163 |
EndSet |
| 164 |
|
| 165 |
EndProperty |
| 166 |
|
| 167 |
PublicFunctionEditingControlWantsInputKey(ByValkeyAsKeys,_ |
| 168 |
ByValdataGridViewWantsInputKeyAsBoolean)AsBoolean_ |
| 169 |
ImplementsIDataGridViewEditingControl.EditingControlWantsInputKey |
| 170 |
|
| 171 |
'LetthenestedDataGridViewhandlethekeyslisted. |
| 172 |
SelectCasekeyAndKeys.KeyCode |
| 173 |
CaseKeys.Left,Keys.Up,Keys.Down,Keys.Right,_ |
| 174 |
Keys.Enter,Keys.Escape,Keys.Tab |
| 175 |
|
| 176 |
ReturnTrue |
| 177 |
|
| 178 |
CaseElse |
| 179 |
ReturnFalse |
| 180 |
EndSelect |
| 181 |
|
| 182 |
EndFunction |
| 183 |
|
| 184 |
PublicSubPrepareEditingControlForEdit(ByValselectAllAsBoolean)_ |
| 185 |
ImplementsIDataGridViewEditingControl.PrepareEditingControlForEdit |
| 186 |
|
| 187 |
'Nopreparationneedstobedone. |
| 188 |
|
| 189 |
EndSub |
| 190 |
|
| 191 |
PublicReadOnlyPropertyRepositionEditingControlOnValueChange()_ |
| 192 |
AsBooleanImplements_ |
| 193 |
IDataGridViewEditingControl.RepositionEditingControlOnValueChange |
| 194 |
|
| 195 |
Get |
| 196 |
ReturnFalse |
| 197 |
EndGet |
| 198 |
|
| 199 |
EndProperty |
| 200 |
|
| 201 |
PublicPropertyEditingControlDataGridView()AsDataGridView_ |
| 202 |
ImplementsIDataGridViewEditingControl.EditingControlDataGridView |
| 203 |
|
| 204 |
Get |
| 205 |
ReturndataGridViewControl |
| 206 |
EndGet |
| 207 |
Set(ByValvalueAsDataGridView) |
| 208 |
dataGridViewControl=value |
| 209 |
EndSet |
| 210 |
|
| 211 |
EndProperty |
| 212 |
|
| 213 |
PublicPropertyEditingControlValueChanged()AsBoolean_ |
| 214 |
ImplementsIDataGridViewEditingControl.EditingControlValueChanged |
| 215 |
|
| 216 |
Get |
| 217 |
ReturnvalueIsChanged |
| 218 |
EndGet |
| 219 |
Set(ByValvalueAsBoolean) |
| 220 |
valueIsChanged=value |
| 221 |
EndSet |
| 222 |
|
| 223 |
EndProperty |
| 224 |
|
| 225 |
PublicReadOnlyPropertyEditingControlCursor()AsCursor_ |
| 226 |
ImplementsIDataGridViewEditingControl.EditingPanelCursor |
| 227 |
|
| 228 |
Get |
| 229 |
ReturnMyBase.Cursor |
| 230 |
EndGet |
| 231 |
|
| 232 |
EndProperty |
| 233 |
|
| 234 |
EndClass | Hope this helps everyone else who is alsolooking for this functionality. | | reachrishikh Thursday, March 12, 2009 8:57 AM | Hello, I am an Italian student and I need to use nested grid in my program written in visual c# 2008. I have translate this code in c# but I don't understand how to use the three class. Can you explain me with an example? I really need to use this structure and this is only documentation thatI found on the net.
Thanks for your reply. | | Turin85 Thursday, July 02, 2009 4:43 PM | Hi, sorry...but I am a noob and want to implement the above code. I have copied the above code in a Module. I wanted something like
Dim MyDatagridView as NestedDGVdatagrid
'then I would use the db biding
could u please provide a sample. sbakazmi@hotmail.com | | sbakazmi Tuesday, September 08, 2009 10:28 PM |
|