|
In the constructor - initialize _widest = 1 rather than 0. Zero is not a valid value and will cause the program to dump if no data is found to put into the combobox.
public DataGridComboBoxColumn(string colName, DataTable dataSource, string displayMember, string valueMember, DataGrid dataGrid)
{
this._comboBox = new ComboBox();
this._comboBox.Visible = false;
this._comboBox.DataSource = dataSource;
this._dataTable = dataSource;
this._comboBox.DisplayMember = displayMember;
this._displayMember = displayMember;
this._valueMember = valueMember;
this._comboBox.ValueMember = valueMember;
this._comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
Graphics _graphicsContext = dataGrid.CreateGraphics();
// if no data is found then _widest == 0 and will dump.
// float _widest=0;
float _widest = 1;
|
|
|
|
|
If the datagrid has nothing in it except datagrid comboboxes, then there is no event to trigger a new row to the data grid after selection.
Also the combobox seems to fail to either go to back and/or re-draw itself properly when the user is selecting choices from comboxes in multiple rows of the data grid.
Suggestions appreciated.
|
|
|
|
|
In the Edit method ... the line
this._comboBox.SelectedValue = instantText;
should be replaced with
this._comboBox.SelectedText = instantText;
if (instantText != null)
{
// this._comboBox.SelectedValue = instantText;
this._comboBox.SelectedText = instantText;
int End = this._comboBox.Text.Length;
this._comboBox.Select(End, 0);
|
|
|
|
|
I want to use MSFlexGrid instead of DataGrid because I want to insert data to the Grid myself. Can you help me?
|
|
|
|
|
It might be easier to create a DataTable on the fly and use that as the datasource for the grid.
PeteB
'I wouldn't say "he's not the sharpest knife", I'd say "he's a spoon."'
|
|
|
|
|
QuynhGiao, you can insert data into DataGrid yourself. Here is some quick sample from this post to create a DataTable on the fly ...
DataTable AccessDataTypes = new DataTable();
AccessDataTypes.Columns.Add(new DataColumn("Number", typeof(int)));
AccessDataTypes.Columns.Add(new DataColumn("Name", typeof(string)));
AccessDataTypes.Rows.Add(new object[] {3, "Numeric"});
AccessDataTypes.Rows.Add(new object[] {130, "Text"});
Hope this help
|
|
|
|
|
How can I realize subj? I have the problem that rows in dataGrid contains different values - each row has own list of items for column with ComboBox.
--
ilia#
|
|
|
|
|
Hi, I just want to know if you get the answer of your question.
And if yes, could you tell me more?
thank you.
|
|
|
|
|
OK, I am not sure if columnComboBox outlined in this artice has the necessary plumbing but I used the component from this website @ http://www.datagridcolumnstyles.net/SuiteI.asp and with the ListFilter event I was able to use different values in each row ... here is also a demo example to review ... http://www.datagridcolumnstyles.net/examples.asp ... titled 'Filter ComboBox Filters'.
On caviar ... the fields need to be of the same datatype ... not sure how critical this is to you.
Good luck and hope this helps.
Robert
|
|
|
|
|
There appears to be a bug that causes the text of non-selected cells to be displayed too close to the top of the cell. This turns out to be a trivial bug.
In the PaintText() method, the call to DrawString() passes the wrong rectangle. The next-to-last parameter should be _rect , not _rectF . In the original code, the offset due to the y margin was effectively being ignored.
|
|
|
|
|
I am encountering a possible bug in the DataGridComboBoxColumn. It occurs if a user enters the combobox and then tries to enter a letter or series of letters (say the letter-S). The error occurs in the override Edit method ...
if (instantText != null)
{
_combobox.SelectedValue = instantText;
int End = ...
System.FormatException - input string was not in correct format.
Has anyone noticed or experienced this problem.
Thanks.
|
|
|
|
|
Hi,
I have several forms that use datagrid.
In all I am using your code.
In some cases it works great I am creating new raw trhtough the grid and recieves a call to your commit method.
But in othere cases when I add new value through the combobox and then click with the mouse else where the combobox cleans up.
Anyway the commit method does not call.
Do you have an idea why?
I tried to look what is the differnces between the forms and the datagrids but I can not found any diff excpet that the table looks like this:
Area:
Area_id
Factory_id
Area_name
Factory:
Factory_id
Factory_name
and in the GRID:
Area_id - regular
Factory_name - combobox
Area_name - regulare
Thanks in advance
Oren.
|
|
|
|
|
- This is hapenning to me no matter how the data is formated.
- This is hapenning in all ComboBoxColumn examples on the Internet (including Microsoft example itself).
- I tried to re-implement the whole class and nothing new.
There is something missing in the commitment of a new row from the ComboBoxColumn class.
Please if anybody has a solution, reply.
Thanks
________________________________________
Dr. Smartee
bishoy8086@hotmail.com
|
|
|
|
|
Cool code, but I'm having a slight problem when adding a new record.
I have a three column DataGrid. The second column has the DataGridComboBox Column. When I add a new record at the bottom of the grid, if I select the ComboBox control first, then try to move to the last field, the ComboBox offsets horizontally to the right covering the column that I would like to edit. If I select the third column first, it works fine.
Can anyone tell me what I'm doing wrong here (see code below)?
private void SetDataGridStyle()
{
// create the TableStyle
this.dgTSRequirements = new System.Windows.Forms.DataGridTableStyle();
this.dgTSRequirements.MappingName = "BUSINESS_REQUIREMENT";
// add the first normal TextBox ColumnStyle
this.dgCSRequirementID = new DataGridTextBoxColumn();
this.dgCSRequirementID.MappingName = "BUSINESS_REQUIREMENT_ID";
this.dgCSRequirementID.Width = 60;
this.dgCSRequirementID.HeaderText = "Number";
this.dgTSRequirements.GridColumnStyles.Add(this.dgCSRequirementID);
// add the ComboBox ColumnStyle
this.dgCSRequirementType = new DataGridComboBoxColumn("BUSINESS_REQUIREMENT_TYPE", this.dataSet11.BUSINESS_REQUIREMENT_TYPE, "BUSINESS_REQUIREMENT_TYPE", "BUSINESS_REQUIREMENT_TYPE"this.dataGrid1);
this.dgCSRequirementType.Width = 128;
this.dgCSRequirementType.HeaderText = "Type";
this.dgCSRequirementType.NullText = "2";
this.dgTSRequirements.GridColumnStyles.Add(this.dgCSRequirementType);
// add the third normal TextBox Column
this.dgCSRequirement = new DataGridTextBoxColumn();
this.dgCSRequirement.MappingName = "BUSINESS_REQUIREMENT";
this.dgCSRequirement.Width = 600;
this.dgCSRequirement.HeaderText = "Requirement";
this.dgTSRequirements.GridColumnStyles.Add(this.dgCSRequirement);
// add the TableStyle to the DataGrid
this.dataGrid1.TableStyles.Add(this.dgTSRequirements);
}
I'm stumped on why when adding a new row to the DataGrid the ComboBox column does an offset to the right obscuring the third row so data cannot be added?
Thanks
|
|
|
|
|
The readonly property of DataGridComboBoxColumn does not seem to be implemented. The following code compiles, but there is no apparent change to the behavior of the column:
DataGridComboBoxColumn myCol = new DataGridComboBoxColumn( "foo", myTable, "Name", "Value", myDGrid);
myCol.NullText = "1";
myCol.HeaderText = "Event Type";
myCol.ReadOnly = true;
myStyle.GridColumnStyles.Add(myCol);
How might I change the code so that, for example, the ComboBox is grayed-out (like the DataGridTextBoxColumn) and does not show the drop-down list then readonly is set to true?
Thanks,
B the ComboBoxColumn
|
|
|
|
|
Hi,
First thanks for the code, it's great.
I just had this problem : when I edit the combobox it works fine, but...
When I click in another populated row, everything is ok.
But when I click in the new row (at the bottom) while editing, this exception is raised : System.FormatException and the debugger stops at this line :
if (instantText!=null)
but instantText IS null
Do you know what the problem may be ?
Thanks
David
|
|
|
|
|
Hi, well I have not seen that error, but I have had others that came up that didn't make sence but I did a few changes ahead of time and like magic it works. I looked in my Edit, which is the only place there is a reference to "instantText", and I have a few more changes:
I had an error which came up if the value was Null, I forget the specifics but this line of code fixed it:
if( (GetText(GetColumnValueAtRow(source, rowNum)) != "") && ((GetText(GetColumnValueAtRow(source, rowNum)) != null)) )
{
_comboBox.SelectedValue = GetText(GetColumnValueAtRow(source, rowNum));
}
It might be realted give it a shot.
|
|
|
|
|
i think the better fix would be instead of
if( (GetText(GetColumnValueAtRow(source, rowNum)) != "") && ((GetText(GetColumnValueAtRow(source, rowNum)) != null)) )
{
_comboBox.SelectedValue = GetText(GetColumnValueAtRow(source, rowNum));
}
you need
_comboBox.SelectedValue = GetColumnValueAtRow(source, rowNum);
without any checks
De O Bolonn
|
|
|
|
|
That's what I did originally, I think, but when I did this, if the GetColumnValueAtRow(source,rowNum) = null, then I think, the _comboBox goes to 0 instead of -1. There was a bug in there somewhere, so I had to add the GetText and the if. And it worked.
It's been awhile so I can't remember the exact bug.
|
|
|
|
|
the error is not within the code...
I had the same problem, untill i found out that my NullText was a string, where it should have been an integer...
so the mapping was this way:
DataGridComboBoxColumn cl = new DataGridComboBoxColumn("type",types,"Type","ID",dgBalen);
with "Type" the string to show, and "ID" the integer value...
Nulltext should be a string containing a value for "ID" (integer in this case)
this solved my problem right away...
|
|
|
|
|
I was using the code that you modified for this posting, that code was so buggy, you really cleaned it up well!
I modified the dropdownlist to a dropdown so the user can add his own info.
It worked with a few modifications:
1) Change the dropdownlist to dropdown in the constructor
2) Change: object _value = _comboBox.SelectedValue;
To: object _value = _comboBox.Text;
in Commit
(allows user data to be saved)
3) Add: _comboBox.Text=GetText(GetColumnValueAtRow(source, rowNum));
at the end of Edit.
(this allows the combobox to show the user data that was previously
entered, and he can now scroll up/down without losing his field)
4) Paint()
I deleted most of it, since it compare the data to the combobox, but if
the user entered data the combobox will not find a match. So I just force
the write everytime by doing this:
string _text = GetText(GetColumnValueAtRow(source, rowNum));
PaintText(g, bounds, _text, alignToRight);
These are the only 2 lines now in Paint.
That's it!
Hope this helps someone else!
If you see any bugs in my modifications, please let me know!
Thanks
|
|
|
|
|
I added a few more changes:
1)
Edit():
Change:
_comboBox.SelectedValue = GetText(GetColumnValueAtRow(source, rowNum));
To:
// Added this if statement to handle an error when the text field was null
if( (GetText(GetColumnValueAtRow(source, rowNum)) != "") && ((GetText(GetColumnValueAtRow(source, rowNum)) != null)) )
{
_comboBox.SelectedValue = GetText(GetColumnValueAtRow(source, rowNum));
}
2)
The .Visible will force the comboBox to be selected at Index 0, but will not display that value. When the user clicks off of the cell (without selecting a dropdown value) the Comit method will save whatever was selected, which would always be whatever was at Index 0. So, we force the Index back to -1, unselected.
After this line: _comboBox.Visible = true;
Add: _comboBox.SelectedIndex=-1;
I also had probs in the Comit() method. Problem was that if you clicked anywhere in the grid the combobox would trigger and whatever value was at index zero of the comboBox would auto-populate the cell. Also if the user did not enter any data the combobox would write a null to the dataSet and trigger the .HasChanges flag. So now this method checks before hand and if the cell in the dataSet is the same as the attepmted save the save will abort.
But now there is no way a user can enter a null, so a null must be included in the drop-down.
Here is the entire method:
///
/// Standard override
///
/// <param name="dataSource" />
/// <param name="rowNum" />
/// <returns>
protected override bool Commit(CurrencyManager dataSource,int rowNum)
{
//if(!_inEdit)
//{
// return true;
//}
// BugFix: Replaced the above if with the if below.
// We had the problem that the combobox would alter the DataSet when in fact it should not.
// This will not abort when the user has not typed anything and the Selected index is -1 (which we set from a proir bugfix)
if(((_comboBox.SelectedIndex==-1)&&(_comboBox.Text=="")) || !_inEdit)
{
Abort(rowNum);
return true;
}
try
{
//object _value = _comboBox.SelectedValue;
object _value = _comboBox.Text;
if(NullText.Equals(_value))
{
_value = System.Convert.DBNull;
}
// Added the if below which will not write a null if the data in the field is the same
// This will avoid setting the .hasChanges flag.
if(this.GetColumnValueAtRow(dataSource, rowNum)!=_value)
this.SetColumnValueAtRow(dataSource, rowNum, _value);
}
catch
{
// This catch will catch when a user enters the wrong data type.
// We store a null value then return true
this.SetColumnValueAtRow(dataSource, rowNum, System.DBNull.Value);
return true;
//return false;
}
finally
{
_inEdit=false;
_comboBox.Hide();
}
return true;
}
The commented out code was code from the original author.
I hope this helps someone.
|
|
|
|
|
I know you've made corrections since this, can you please post them?
Thanks so much!!!
|
|
|
|
|
Hello,
I have arequirement where I am supposed to wrap the text shown in a cell in the datagrid. What actually needs to be done is that the cell should grow in height to show its entire content.
Can anyone out there help me please ?
Jay.
|
|
|
|
|
This is a great piece of code! Thank you very much for sharing it!
Here's a couple things that I had to figure out that I hope will help others as they build this into their projects:
When setting the NullText property, note that this is really the default index of the ComboBox. So you'll probably want to set it to "0" so the first item will be selected when inserting new rows. I guess I didn't understand that from the article.
The first parameter of the constructor, "colName" must be the name of the column in the dataset that is being updated. The HeaderText property is set by default to this name, but you can change it if you want the column's name to appear differently in the DataGrid.
Again, thanks for the code!
|
|
|
|