On the smart client developer center i read the following
http://msdn.microsoft.com/smartclient/understanding/windowsforms/2.0/features/datagridview.aspx
The DataGridView comes with TextBox, Image, CheckBox, ComboBox, Link, and Button column and cell types. Addition cell or column types can be easily implemented to extend your application. Columns and rows both support heterogeneous cell types. For example, you can have column of check box cells and have other cell types, like a button, in the same column
Since this is exactly what I needed, I started searching for documentation and examples. Perhaps i did something wrong cause all i could find was documentation and examples of how to create DataGridViewColumns resulting in columns with only buttons, or textboxes. The interesting pages i did found were not completely finished ( The examples were lacking ).
Does anyone know how to achieve multiple DataGridViewCell types ( say a DataGridViewButton and a DataGridViewComboBox ) in the same column
Or can anyone provide me some documentation
Thanx in advance

DataGridView and Heterogenous cell types
Nitin Badole
This is kinda tricky since in your case the real value is a string value but you want to display an image. What you can do in this case is create a simple cell/column type that inherits from image cell/column that does what you want. Here is some code to get you started. You'll just need to fill in the GetFormatedValue method to load your image (probably use Image.FromFile(filename)).
public class CustomImageColumn : DataGridViewImageColumn
{
public CustomImageColumn()
{
this.CellTemplate = new CustomImageCell();
this.ValueType = typeof(string);
}
}
public class CustomImageCell : DataGridViewImageCell
{
static Image emptyImage;
static CustomImageCell()
{
emptyImage = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
}
public CustomImageCell()
{
this.ValueType = typeof(string);
}
protected override object GetFormattedValue(object value,
int rowIndex, ref DataGridViewCellStyle cellStyle,
TypeConverter valueTypeConverter,
TypeConverter formattedValueTypeConverter,
DataGridViewDataErrorContexts context)
{
if (value.ToString() != String.Empty) {
// load image from disk
} else {
return emptyImage;
}
}
public override object DefaultNewRowValue
{
get
{
return String.Empty;
}
}
}
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
setuc
Except when i try to create an imagecell it only works when the DataGridView is not databound. I keep getting data error exceptions that say :
System.FormatException: Formatted value of the cell has a wrong type
When i look at the FormattedValue and FormattedValueType, then these are of type System.Drawing.Bitmap and System.Drawing.Image even the ValueType is of type System.Drawing,Image, but for some reason the value is empty.
I think the problem is that in the datasource the image is stored as base64 text, and for my debug environment i load the same picture from my harddrive for every occurence of a picture file ( this specified by the so called domainId column ). Could this be it
Anyone any experience in changing te celltypes to a DataGridViewImageCell when the datasource bound to only contains text columns
bonsai1
For Each row As DataGridViewRow In ProductsDataGridView.Rows
row.Cells(0) = New DataGridViewLinkCell()
Next
and this works. You won't be able to replace a cell directly with a combobox cell because you will encounter a DataError (assuming the cell has a value). You'll need to create a combobox cell and fill in the values and then set it to replace the cell. Something like this:
For Each row As DataGridViewRow In ProductsDataGridView.Rows
Dim c As DataGridViewComboBoxCell = New DataGridViewComboBoxCell()
If row.Cells(0).Value IsNot Nothing Then
c.Items.Add(row.Cells(0).Value)
End If
row.Cells(0) = c
Next
-mark
DataGridView Program Manager
Microsoft
this post is provided "as-is"
Michael William
The DataGridView supports heterogenous cells by the following methods:
1) Set a cell reference to a new cell type like so:
dataGridView1[3,3] = new DataGridViewButtonCell();
2) Adding a row with the cell types you want like so:
DataGridView1.Rows.Add(New DataGridViewButtonCell())
Hope this helps,
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
FvS
This is the most performant way of doing this vs. replacing cell types after you are databound.
That said, what you are doing is the correct way if you don't need to replace *all* cell entries with a new type (heterogenous).
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
Mark Wistrom
The thing is we have a CMS web application, for which i am building a smart client. The smart client retrieves a xml file that contains data in a complex structure
the values of the data are of different types.
for example the following values will appear
showonsite -> ( yes / no ) ->combobox
companylogo -> ( Image ) -> customImageEditControl
SystemId -> Integer read only value
description -> HTML -> custom HTML edit Control
but since the most attributes will be simple site content and this is stored as plain text, so that is why i only wanted to replace some wel say one fourth of all cells. I also was thinking about using multiple datasource filtered by domainId ( by cell type ) but this probably will cause other grouping and sorting difficulties
The company expects me to create a sort of the same look and feel as the old web based cms, which means that all attributes and values have to displayed on one page, but is has to be faster than the web cms which has troubles when the attributes reach over 10000 which is happening more and more often as our customers get bigger.
Thanx for the advise to override the GetFormattedValue method.
Still need to get more familiar with this component.
Mooseboy2358
aak
First of all thanx for your response, but what i forgot to mention was that the DataGridView is DataBound to a dataset.
Since it is possible for the dataset to contain 36000 or more rows i figured that i wouldn't want to fill the DataGridView by hand ( using a for loop for example ).
And i already noticed that changing a celltemplate does nothing when your datagridview is databound , here is the code i used for testing purposes.
if (dataGridView1.Rows[x].Cells["domainId"].Value.ToString().Trim() == "7")
dataGridView1[
"domainId",x] = new DataGridViewComboBoxCell();but this doesn't seem to have any effect.
Thanx again for your help
Richard Turner - MSFT
if have a view with to columns, the first a DataGridViewComboBoxCell and the second a simple textbox cell.
The data is not bound to a data source.
Filling up the text cell is no problem, the text displays fine, but the comboboxes won't work. In each combobox i need the same three values (let's say val1, val2 and val3) but the initial selection can be different.
i've tried to fill the the combobox in various ways: throug the designer (just adding strings) and with code like this: (in wich DGV is my dataGridView)
DataGridViewRow
row = new DataGridViewRow(); DataGridViewComboBoxCell cell1 = new DataGridViewComboBoxCell();cell1.Items.Add("val1"
);cell1.Items.Add("val2"
);cell1.Items.Add(
"val3"); DataGridViewTextBoxCell cell2 = new DataGridViewTextBoxCell();cell2.Value ="Text" ;
row.Cells.Add(cell1);
row.Cells.Add(cell2);
DGV.Rows.Add(row);
If i run my program i'm not able to select a value (the list won't drop down) but in debug mode i can see that the values are actually in the Items collection of the ComboboxCell.
It seemed to me that a comboBoxCell would work as an normal comboBox (and i think it should) but apparently it doesn't.
Any help is appreciated