How to convert DataGridViewComboBoxCell to DataGridViewTextBoxCell - c#

I searched a lot for this error many same question is already asked, but its not solving my problem.
I am getting
Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.
The scenario is I have datagridview with TextboxColumn I am using CellBeginEdit to convert it in ComboBoxColumn, and after CellValidate I again change ComboBoxColumn to TextboxColumn. The codes works for all. but getting said error in exact line e.RowIndex = 2 throws this exception, but others rows doses not show error. if I omit this error and continue then e.RowIndex = 2 cell value comes blank, and other rows value work.
Here is the code of CellBeginEdit
if (e.ColumnIndex == 2 && e.RowIndex >= 0)
{
try
{
string s = Convert.ToString(_dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex].Value);
string s1 = Convert.ToString(_dgvCoarseAggegateTest[e.ColumnIndex, 0].Value);
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
string _SizeName = _cGetParrent._mGetParentCellValue(ref _dgvCoarseAggegateTest, e.RowIndex, 1);
_mFillSieveSizeGridCombo(_mGetMetalSizeID(_SizeName), ref c); // Here My Combo Will GetValues from SQL and it Returning Value
_dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex] = c; // Heres the error When e.RowIndex == 2 and if e.RowIndex != 2 then no error
_dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex].Value = s;
_dgvCoarseAggegateTest[e.ColumnIndex, 0].Value = s1;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
How to resolve this.
UPDATE :
No rows there user will add new row and select values, the base thing is i want to show combo and fill values from database, the fill values is depends on condition, so every time new values will come,
Sample Data
testTable
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
9 I
In column1 I added one combo with values from 1 to 9, in _mFillSieveSizeGridCombo I am passing id to sql server 2008 and filling combo using Combo.Item.Add(x) method.

There is a flag inside SetCurrentCellAddressCore() preventing any re-entrant call corrupting internal values of DataGridView. Usaully an event was raised with the flag = true and reset at the end of event.
To workaround this, you can simply add a wrapper of BeginInvoke() inside the event, to get your process run after the event with async.
EDIT
The issue can be reproduce in EditOnEnter mode, and the setter of cell outside the event in BeginInvoke results the indefinite loop
private bool _suppressCellBeginEdit = false;
private void dgv_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
var dgv = sender as DataGridView;
if (_suppressCellBeginEdit)
return;
if (e.ColumnIndex == 2 && e.RowIndex >= 0)
{
string s = Convert.ToString(dgv[e.ColumnIndex, e.RowIndex].Value);
string s1 = Convert.ToString(dgv[e.ColumnIndex, 0].Value);
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 0));
c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 1));
c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 2));
// special handling
if (e.RowIndex == e.ColumnIndex)
{
this.BeginInvoke(new Action(() =>
{
_suppressCellBeginEdit = true;
this.Invoke(new Action(() =>
{
c.Value = s;
dgv[e.ColumnIndex, e.RowIndex] = c;
dgv[e.ColumnIndex, 0].Value = s1;
}));
_suppressCellBeginEdit = false;
}));
}
else
{
c.Value = s;
dgv[e.ColumnIndex, e.RowIndex] = c;
dgv[e.ColumnIndex, 0].Value = s1;
}
}
}

As you can tell from the trouble you are having implementing this, DataGridView is very unhappy about you trying to pull the floor mat. It explicitly forbids changing the cell object at critical moments. While it is handling an event itself is such a critical moment. A generic problem with events, called re-entrancy. The trouble you are having with #Eric's approach shows that it is indeed a tricky issue to solve.
So what you do not want to do is modify the cell type or reference. Keep your eyes on the ball, what you really want to do is modify the content of the dropdown list. That is not a problem. Get back to the designer and change the ColumnType property of the column to DataGridViewComboBoxColumn. And use the CellBeginEdit event to dynamically alter the combobox items collection. A simple example:
private void _dgvCoarseAggegateTest_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) {
var dgv = (DataGridView)sender;
if (e.ColumnIndex == 2) {
var cell = (DataGridViewComboBoxCell)dgv.Rows[e.RowIndex].Cells[e.ColumnIndex];
cell.Items.Clear();
// Run your dbase query here to fill cell.Items
//...
// We'll just fake it here for demo purposes:
cell.Items.Add(e.RowIndex.ToString());
cell.Items.Add((e.RowIndex+1).ToString());
cell.Items.Add((e.RowIndex+2).ToString());
}
}

Here is a workaround: In the CellBeginEdit event first check to see if the ColumnType is DataGridViewComboBoxCell. If it isn't we cancel the event, call a function that changes the column type and then call the event once more:
void switchCellType(object sender, DataGridViewCellCancelEventArgs e)
{
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
// prepare the cell:
//..
// fill the drop down items..
c.Items.Add("1"); // use
c.Items.Add("2"); // your
c.Items.Add("3"); // code here!
DGV[e.ColumnIndex, e.RowIndex] = c; // change the cell
DGV_CellBeginEdit(sender, e); // restart the edit with the original parms
}
private void DGV_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
DataGridViewCell cell = DGV[e.ColumnIndex, e.RowIndex];
if (!(cell is DataGridViewComboBoxCell))
{
e.Cancel = true;
switchCellType(sender, e);
return;
}
//..
Now your code can proceed, obviously without the cell changing. Possibly you want to pass in the text value to set as well..
Note that you will have to make sure that the CellEndEdit event doesn't revert the change before its time!! Maybe a flag, maybe in the Tag will help. If you want I can have a look at your CellEndEdit code, if there is any..

Related

Make the first character upper case of a string in Win Form DataGridView C#.NET

So, I have a data grid view in my C# Win Form application, the cells are editable by default, now I want whenever something is typed in those cell the end value should be treated as Upper Case First, so which means If any user types:
*string => String
example => Example
another => Another
chaRactEr => ChaRactEr*
I can do this in my code in the Cell Value Changed event, but when I do this in the Cell Value Changed event and set the value of that cell as the formatted string (Which is required from end-user) the event gets triggered twice. I can't let this happened since there is a database functionality triggering in this event.
I have tried capturing the cell value in other event like Cell Leave, Cell Enter and other events, but never can I capture it.
So I need to know, If there is a any property or characteristic of the Data Grid View in C#.NET which would make the first character of the value as upper case?
Any alternate suggestion to this would also be really helpful.
You can use this code:
bool bchange = false;
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (bchange == false)
{
bchange = true;
String oritext = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
String newtext= oritext.First().ToString().ToUpper() + oritext.Substring (1);
//Update Database
//Update cell
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = newtext;
}
else
{
bchange = false;
}
}
DataGridView has an event 'CellFormatting'. You can go for something like this:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.Value != null)
{
string str = (string)e.Value;
str = char.ToUpper(str[0]) + str.Substring(1);
e.Value = str;
}
}
I can only guess you may be neglecting that when the code “changes” the value in the “cell” that called the CellValueChanged event, will obviously “fire” the CellValueChanged event again when its value is changed to have an upper case string!
To avoid this circular reference, simply turn the event “off” (before you change the cells value), change the cells value… the event will not fire… then turn the event back “on" after the value has changed.
Example; Below checks to see if the cell changed is in column 0, changes the string in the cell to make the first character an upper case character. The code utilizes a text box on the form that will contain text indicating when the CellValueChanged event is fired. If the code runs with the commented code as posted, the text box will contain two (2) entries every time a cell value in column one changes. UN-commenting the two lines of code will show the text box entry will have only one (1) entry. Sandwich the line of code that “changes” the cells value between the line of code that turns the event “off” and the line of code that turns it back “on”. Hope this makes sense.
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (e.RowIndex >= 0 && e.ColumnIndex >= 0) {
if (e.ColumnIndex == 0 && dataGridView1.Rows[e.RowIndex].Cells[0].Value != null) {
string currentData = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
string newData = char.ToUpper(currentData[0]) + currentData.Substring(1);
//dataGridView1.CellValueChanged -= new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
dataGridView1.Rows[e.RowIndex].Cells[0].Value = newData;
//dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
textBox3.Text += "CellValueChanged fired!" + Environment.NewLine;
}
}
}

C# datagridview cell value edit is undone after changing current cell

I hope you can help me. I didn't find a solution which fits my problem by googling.
I have a DataGridView with no bound data. When the user double-clicks in a cell he can write a new value into the cell. Based on the change, the value in the neighbour-cell is changed too. This is working properly so far.
Now I want to set some conditions, like thresholds and if the user is out of the range the value in the edited cell should be corrected.
The value in the neighbour-cell is still calculated right, but the value in the user-edited cell always stays at the user input value.
I already tried several combinations of BeginEdit() and CurrentCell..., but always the same.
Here is my actual code for the cellvalueChanged Event:
private void dgSpotInfo_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (cellvaluechangend)
{
cellvaluechangend = false;
int mod_Int_index = dgSpotInfo.Columns.IndexOf(dgSpotInfo.Columns["col_modifiedIntensity"]);
dgSpotInfo.EditMode = DataGridViewEditMode.EditProgrammatically;
dgSpotInfo.BeginEdit(true);
int val;
if (e.ColumnIndex == mod_Int_index) // if the modified Intensity value is changed
{
val = (Convert.ToInt32(dgSpotInfo[mod_Int_index, e.RowIndex].Value) - Convert.ToInt32(spot_analysis.GetFoundSpots[e.RowIndex].ModifiedIntensity));
// here is tested if the value is too high
if (Convert.ToInt32(dgSpotInfo[mod_Int_index, e.RowIndex].Value) > 255)
{
// here is the problem, during debugging the value is displayed right,
// but afterwards the current cell it is displayed as the too high value again
dgSpotInfo[mod_Int_index, e.RowIndex].Value = "255";
val = (Convert.ToInt32(dgSpotInfo[mod_Int_index, e.RowIndex].Value) - Convert.ToInt32(spot_analysis.GetFoundSpots[e.RowIndex].ModifiedIntensity));
}
dgSpotInfo.CurrentCell = dgSpotInfo[modifier_index, e.RowIndex];
dgSpotInfo[modifier_index, e.RowIndex].Value = Convert.ToString(val);
}
dgSpotInfo.EndEdit();
dgSpotInfo.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
dgSpotInfo.ReadOnly = true;
}
}
and here for my clicking event:
private void dgSpotInfo_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
// Testing if the clicked cell is allowed to change
if (((e.ColumnIndex == dgSpotInfo.Columns.IndexOf(dgSpotInfo.Columns["col_modifiedIntensity"])) || (e.ColumnIndex == dgSpotInfo.Columns.IndexOf(dgSpotInfo.Columns["col_Modifier"]))) && e.RowIndex >= 0)
{
dgSpotInfo.CurrentCell = dgSpotInfo[e.ColumnIndex, e.RowIndex];
dgSpotInfo.ReadOnly = false;
dgSpotInfo.BeginEdit(true);
cellvaluechangend = true;
}
}
I hope I descriped my problem understandable and you can help me.
Tanks!
If someone has a similar problem:
I solved the problem by adding a CellEndEdit event. After the user edited the cell I am doing the threshold validation like above now in the CellEndEdit event handler. I don't know why, but maybe it is so, that in the event handler which is caused by the editing you cannot undo the editing.

Convert Combobox to Textbox in Gridview C#

i have an combobox cell and i wanna convert to textbox cell after select item from the same combobox cell and convert to textbox but the problem when using
[1, DataGridView1.CurrentRow.Index] = new DataGridViewTextBoxCell()`
the cell not change until click on another cell although i'm using Datagridview1.refresh()
the first picture (when select from combobox then it should be changed )
the second picture ( after click an another cell )
DataGridViewComboBoxCells are notoriously obtuse when it comes to such a simple thing as simply and fully accepting a selected value..
This seems to work for me:
ComboBox editComboBox = null;
private void DataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox && e.ColumnIndex == 1)
{
editComboBox = (ComboBox)e.Control;
editComboBox.SelectionChangeCommitted -= editComboBox_SelectionChangeCommitted;
editComboBox.SelectionChangeCommitted += editComboBox_SelectionChangeCommitted;
}
}
void editComboBox_SelectionChangeCommitted(object sender, EventArgs e)
{
DataGridView1[1, dataGridView5.CurrentRow.Index] = new DataGridViewTextBoxCell();
DataGridView1[1, dataGridView5.CurrentRow.Index].Value =
editComboBox.SelectedItem.ToString();
DataGridView1.EndEdit();
DataGridView1[1, dataGridView5.CurrentRow.Index]cell1.Selected = false;
editComboBox = null;
}
Note that calling EndEdit allegedly can raise an exception if no error handler is found. I don't have one and I still don't get an error. Not sure what the docs mean; maybe that it may raise an error if the data are in fact invalid..
Also note that with this design the user can not easily correct an edit, unless you provide a way to restore the dropdown..

C# DataGridViewCheckBoxColumn Hide/Gray-Out

I have a DataGridView with several columns and several rows of data. One of the columns is a DataGridViewCheckBoxColumn and (based on the other data in the row) I would like the option to "hide" the checkbox in some rows. I know how to make it read only but I would prefer it to not show up at all or at least display differently (grayed out) than the other checkboxes. Is this possible?
Some workaround: make it read-only and change back color to gray.
For one specific cell:
dataGridView1.Rows[2].Cells[1].Style.BackColor = Color.LightGray;
dataGridView1.Rows[2].Cells[1].ReadOnly = true;
Or, better but more "complicated" solution:
suppose you have 2 columns: first with number, second with checkbox, that should not be visible when number > 2. You can handle CellPainting event, paint only borders (and eg. background) and break painting of rest. Add event CellPainting for DataGridView (optionally test for DBNull value to avoid exception when adding new data in empty row):
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
//check only for cells of second column, except header
if ((e.ColumnIndex == 1) && (e.RowIndex > -1))
{
//make sure not a null value
if (dataGridView1.Rows[e.RowIndex].Cells[0].Value != DBNull.Value)
{
//put condition when not to paint checkbox
if (Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[0].Value) > 2)
{
e.Paint(e.ClipBounds, DataGridViewPaintParts.Border | DataGridViewPaintParts.Background); //put what to draw
e.Handled = true; //skip rest of painting event
}
}
}
}
It should work, however if you change value manually in first column, where you check condition, you must refresh the second cell, so add another event like CellValueChanged:
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0)
{
dataGridView1.InvalidateCell(1, e.RowIndex);
}
}
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcheckboxcell.aspx
DataGridViewCheckBoxCell.Visible = false;
Edit: Oh, wait, it's read only. Derp.
In which case, try replacing the cell with an empty DataGridViewTextBoxCell.
Taken from Customize the Appearance of Cells in the Windows Forms DataGridView Control, you could catch the CellPainting event and not draw the cell if its in read only mode. For example:
public Form1()
{
InitializeComponent();
dataGridView1.CellPainting += new
DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);
}
private void dataGridView1_CellPainting(object sender,
System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
{
// Change 2 to be your checkbox column #
if (this.dataGridView1.Columns[2].Index == e.ColumnIndex && e.RowIndex >= 0)
{
// If its read only, dont draw it
if (dataGridView1[e.ColumnIndex, e.RowIndex].ReadOnly)
{
// You can change e.CellStyle.BackColor to Color.Gray for example
using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
{
// Erase the cell.
e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
e.Handled = true;
}
}
}
}
The only caveat is that you need to call dataGridView1.Invalidate(); when you change the ReadOnly property of one of the DataGridViewCheckBox cell's.

Datagridview: How to set a cell in editing mode?

I need to programmatically set a cell in editing mode. I know that setting that cell as CurrentCell and then call the method BeginEdit(bool), it should happen, but in my case, it doesn't.
I really want that, with my DGV with several columns, the user can ONLY select and also edit the first two. The other columns are already read-only, but the user can select them, and that is what I don't want.
So I was thinking, tell the user to TAB everytime it has finished writing on the cell, then select the second cell, then tab again and it select and begin edit the next row's first cell...
How can I do this?
Setting the CurrentCell and then calling BeginEdit(true) works well for me.
The following code shows an eventHandler for the KeyDown event that sets a cell to be editable.
My example only implements one of the required key press overrides but in theory the others should work the same. (and I'm always setting the [0][0] cell to be editable but any other cell should work)
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab && dataGridView1.CurrentCell.ColumnIndex == 1)
{
e.Handled = true;
DataGridViewCell cell = dataGridView1.Rows[0].Cells[0];
dataGridView1.CurrentCell = cell;
dataGridView1.BeginEdit(true);
}
}
If you haven't found it previously, the DataGridView FAQ is a great resource, written by the program manager for the DataGridView control, which covers most of what you could want to do with the control.
private void DgvRoomInformation_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (DgvRoomInformation.CurrentCell.ColumnIndex == 4) //example-'Column index=4'
{
DgvRoomInformation.BeginEdit(true);
}
}
Well, I would check if any of your columns are set as ReadOnly. I have never had to use BeginEdit, but maybe there is some legitimate use. Once you have done dataGridView1.Columns[".."].ReadOnly = False;, the fields that are not ReadOnly should be editable. You can use the DataGridView CellEnter event to determine what cell was entered and then turn on editing on those cells after you have passed editing from the first two columns to the next set of columns and turn off editing on the last two columns.
I know this question is pretty old, but figured I'd share some demo code this question helped me with.
Create a Form with a Button and a DataGridView
Register a Click event for button1
Register a CellClick event for DataGridView1
Set DataGridView1's property EditMode to EditProgrammatically
Paste the following code into Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
DataTable m_dataTable;
DataTable table { get { return m_dataTable; } set { m_dataTable = value; } }
private const string m_nameCol = "Name";
private const string m_choiceCol = "Choice";
public Form1()
{
InitializeComponent();
}
class Options
{
public int m_Index { get; set; }
public string m_Text { get; set; }
}
private void button1_Click(object sender, EventArgs e)
{
table = new DataTable();
table.Columns.Add(m_nameCol);
table.Rows.Add(new object[] { "Foo" });
table.Rows.Add(new object[] { "Bob" });
table.Rows.Add(new object[] { "Timn" });
table.Rows.Add(new object[] { "Fred" });
dataGridView1.DataSource = table;
if (!dataGridView1.Columns.Contains(m_choiceCol))
{
DataGridViewTextBoxColumn txtCol = new DataGridViewTextBoxColumn();
txtCol.Name = m_choiceCol;
dataGridView1.Columns.Add(txtCol);
}
List<Options> oList = new List<Options>();
oList.Add(new Options() { m_Index = 0, m_Text = "None" });
for (int i = 1; i < 10; i++)
{
oList.Add(new Options() { m_Index = i, m_Text = "Op" + i });
}
for (int i = 0; i < dataGridView1.Rows.Count - 1; i += 2)
{
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
//Setup A
c.DataSource = oList;
c.Value = oList[0].m_Text;
c.ValueMember = "m_Text";
c.DisplayMember = "m_Text";
c.ValueType = typeof(string);
////Setup B
//c.DataSource = oList;
//c.Value = 0;
//c.ValueMember = "m_Index";
//c.DisplayMember = "m_Text";
//c.ValueType = typeof(int);
//Result is the same A or B
dataGridView1[m_choiceCol, i] = c;
}
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
{
if (dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns.IndexOf(dataGridView1.Columns[m_choiceCol]))
{
DataGridViewCell cell = dataGridView1[m_choiceCol, e.RowIndex];
dataGridView1.CurrentCell = cell;
dataGridView1.BeginEdit(true);
}
}
}
}
}
Note that the column index numbers can change from multiple button presses of button one, so I always refer to the columns by name not index value. I needed to incorporate David Hall's answer into my demo that already had ComboBoxes so his answer worked really well.
The question is old, but the proposed solutions did not help in my situation.
It was necessary to select the cell when loading the form.
This option did not work:
private void FOperations_Load(object sender, EventArgs e)
{
dgvOperations.CurrentCell = dgvOperations[nameof(Operation.DisplayName), 0];
dgvOperations.Select();
}
If you make a cell selection in the "Layout" event, then everything is successful:
private void dgvOperation_Layout(object sender, LayoutEventArgs e)
{
dgvOperations.CurrentCell = dgvOperations[nameof(Operation.DisplayName), 0];
dgvOperations.Select();
}
I know this is an old question, but none of the answers worked for me, because I wanted to reliably (always be able to) set the cell into edit mode when possibly executing other events like Toolbar Button clicks, menu selections, etc. that may affect the default focus after those events return. I ended up needing a timer and invoke. The following code is in a new component derived from DataGridView. This code allows me to simply make a call to myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName); anytime I want to arbitrarily set a databound cell to edit mode (assuming the cell is Not in ReadOnly mode).
// If the DGV does not have Focus prior to a toolbar button Click,
// then the toolbar button will have focus after its Click event handler returns.
// To reliably set focus to the DGV, we need to time it to happen After event handler procedure returns.
private string m_SelectCellFocus_DataPropertyName = "";
private System.Timers.Timer timer_CellFocus = null;
public void CurrentRow_SelectCellFocus(string sDataPropertyName)
{
// This procedure is called by a Toolbar Button's Click Event to select and set focus to a Cell in the DGV's Current Row.
m_SelectCellFocus_DataPropertyName = sDataPropertyName;
timer_CellFocus = new System.Timers.Timer(10);
timer_CellFocus.Elapsed += TimerElapsed_CurrentRowSelectCellFocus;
timer_CellFocus.Start();
}
void TimerElapsed_CurrentRowSelectCellFocus(object sender, System.Timers.ElapsedEventArgs e)
{
timer_CellFocus.Stop();
timer_CellFocus.Elapsed -= TimerElapsed_CurrentRowSelectCellFocus;
timer_CellFocus.Dispose();
// We have to Invoke the method to avoid raising a threading error
this.Invoke((MethodInvoker)delegate
{
Select_Cell(m_SelectCellFocus_DataPropertyName);
});
}
private void Select_Cell(string sDataPropertyName)
{
/// When the Edit Mode is Enabled, set the initial cell to the Description
foreach (DataGridViewCell dgvc in this.SelectedCells)
{
// Clear previously selected cells
dgvc.Selected = false;
}
foreach (DataGridViewCell dgvc in this.CurrentRow.Cells)
{
// Select the Cell by its DataPropertyName
if (dgvc.OwningColumn.DataPropertyName == sDataPropertyName)
{
this.CurrentCell = dgvc;
dgvc.Selected = true;
this.Focus();
return;
}
}
}
I finally found an answer to this. In my case, I wanted to select a specific index or item after adding a new row, but this should apply to other situations.
The cell doesnt hold the combobox controls per say. The DGV does, it holds the controls of the current cell. So you have to make the current cell the combo cell, then go in edit mode, then cast the dgv controls as ComboBox, then you will have access to the selectedIndex and selectedItem methods
Dim rowIndex = myDgv.Rows.Add()
myDgv.ClearSelection()
myDgv.CurrentCell = myDgv.Rows(rowIndex).Cells("colName")
myDgv.BeginEdit(True)
Dim myCombo as ComboBox = CType(myDgv.EditingControl, ComboBox)
myCombo.SelectedIndex = 3

Categories

Resources