combobox automatically selecting a value - c#

I using a System.Windows.Forms.ComboBox and I'm getting some weird unexpected behavior. In c#, I am dynically adding a few comboBoxes to my form and binding them to a list. The only fields I'm setting are DataSource,ValueMember, and DisplayMember. For some reason, after I bind to the list, the first item is selected. I cannot figure out what's going on.
My code looks like this:
Control c = new System.Windows.Forms.ComboBox();
Looping through all my controls,
if (c?.GetType() == typeof (ComboBox))
{
BindComboBox((ComboBox) c);
}
private void BindComboBox(ComboBox sender)
{
DataTable table = DataGateway.GetTables(1);
sender.DataSource = table;
sender.ValueMember = "ID";
sender.DisplayMember = "Name";
//sender.SelectedIndex = -1; I tried with this and without this
}
I also tried a second method but the same thing is happening -
private void BindComboBox(ComboBox sender)
{
List<string> hiStrings = new List<string>() {"hi", "hello", "whats up"};
sender.DataSource = hiStrings;
}

First value is selected but is default behavior when You don't nothing change in ComboBox class settings
Modify the second method:
private void BindComboBox(ComboBox sender)
{
List<string> hiStrings = new List<string>() {"hi", "hello", "whats up"};
sender.DataSource = hiStrings;
sender.SelectedItem = null;
}
And this give You empty ComboBox on Form
This solution is working and I tested.
Some helps links:
How to deselect the text of a combobox
Test method:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void comboBox1_MouseLeave(object sender, EventArgs e)
{
var comboBox = sender as ComboBox;
this.TestMethod(comboBox);
}
private void TestMethod(ComboBox d)
{
var list = new List<string>() {"hi", "hello", "whats up"};
d.DataSource = list;
d.SelectedItem = null;
}
}

Related

Dynamically add item to DataGridView ComboBox Column by typing in the cell

I have a DataGridView that has a ComboBox column and I must update each ComboBox's possible values when its drop down shows. I also must make the ComboBoxes capable of having custom typed values. When a new value is typed, it should be added to the list of possible values. The problem is that I get infinitely many DataError event triggers (error message boxes), I know how to handle it by just changing a field in the DataGridViewDataErrorEventArgs object, but I know it is not the correct way to handle it:
private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = false;
}
If I do it in the incorrect way, after selecting a value from the drop down or typing a new value, the CellValueChanged is triggered but the closed ComboBox does not display the current value but an already existing value (the first in the list).
In the following code the Form subclass is Form2, the initial values are stored in the str field and the UpdatePossibleValues method is called to update the possible values in all the ComboBoxes inside the only column in the data grid view, a DataGridViewComboBoxColumn:
public Form2()
{
InitializeComponent();
dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;
UpdatePossibleValues();
}
internal List<string> str = new List<string>()
{
"val1",
"val2"
};
private void DataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentCell == null ||
dataGridView1.CurrentCell.OwningColumn == null ||
dataGridView1.CurrentCell.OwningColumn.Name != "column1")
{
return;
}
var combo = e.Control as DataGridViewComboBoxEditingControl;
if (combo == null)
{
return;
}
var cb = combo as ComboBox;
UpdatePossibleValues(cb);
cb.DropDownStyle = ComboBoxStyle.DropDown; // this makes the ComboBoxes editable
cb.Validating += Cb_Validating;
}
private void Cb_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
var cbo = sender as ComboBox;
string t = cbo.Text;
var cell = (DataGridViewComboBoxCell)dataGridView1.CurrentCell;
// add the value to the list if it is not there
if (!string.IsNullOrEmpty(t) &&
!cbo.Items.Contains(t))
{
str.Add(t);
UpdatePossibleValues(cbo);
cell.Value = t;
e.Cancel = false;
}
}
private void UpdatePossibleValues(ComboBox cb = null)
{
if (cb == null)
{
var col = dataGridView1.Columns[0] as DataGridViewComboBoxColumn;
col.Items.Clear();
foreach (string s in str)
{
col.Items.Add(s);
}
}
else
{
cb.Items.Clear();
foreach (string s in str)
{
cb.Items.Add(s);
}
}
}
Screenshots:
To dynamically add item to DataGridViewComboBoxColumn:
Hanlde EditingControlShowing and get the DataGridViewComboBoxEditingControl
Set editing control DropDownStyle to DropDown
Handle Validating event of editing control and make sure you attach the event handler just once.
Check if the Text of the editing control doesn't exists in the items:
Add it to data source of the column
Then reset data source of the column by setting it to null and assigning data source again.
Notes:
If you have multiple combo box, make sure you use different data sources for combo boxes and update corresponding data source in validating event.
If you handle the events using anonymous method, make sure you have a correct assumption about captured variables. To make it simple, you can handle the event using a normal method.
Example
The following example shows a DataGridView having two DataGridViewComboBoxColumn which for the second one, you can add new values by typing in the combo box at run-time.
To run the example, create a Form and drop a DataGridView on a new Form and just copy and paste the following code in the form:
private List<String> comboSource1;
private List<String> comboSource2;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
comboSource1 = new List<string> { "A", "B" };
comboSource2 = new List<string> { "1", "2" };
var dt = new DataTable();
dt.Columns.Add("C1");
dt.Columns.Add("C2");
dt.Rows.Add("A", "1");
dt.Rows.Add("B", "2");
var c1 = new DataGridViewComboBoxColumn();
c1.Name = "C1";
c1.DataPropertyName = "C1";
c1.DataSource = comboSource1;
var c2 = new DataGridViewComboBoxColumn();
c2.Name = "C2";
c2.DataPropertyName = "C2";
c2.DataSource = comboSource2;
dataGridView1.Columns.AddRange(c1, c2);
this.dataGridView1.DataSource = dt;
dataGridView1.EditingControlShowing += dataGridView1_EditingControlShowing;
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
}
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
var dataGridView = sender as DataGridView;
if (dataGridView?.CurrentCell?.ColumnIndex != 1) return;
var comboBox = e.Control as DataGridViewComboBoxEditingControl;
if (comboBox == null) return;
comboBox.DropDownStyle = ComboBoxStyle.DropDown;
if (!true.Equals(comboBox.Tag))
{
comboBox.Tag = true;
comboBox.Validating += (obj, args) =>
{
var column = (DataGridViewComboBoxColumn)dataGridView.CurrentCell.OwningColumn;
var list = comboBox.DataSource as List<string>;
if (list == null) return;
var txt = comboBox.Text;
if (!list.Contains(txt))
{
list.Add(txt);
column.DataSource = null;
column.DataSource = list;
}
dataGridView.CurrentCell.Value = txt;
dataGridView.NotifyCurrentCellDirty(true);
};
}
}

Item in ListBox can have different value in textbox?

I have this ListBox that displays items I dragged from my DataGridView. Items in ListBox displays their MenuCode. What I want to happen is I want to show the MenuPrice of each item I have on ListBox on a TextBox. I tried to do this but the MenuCode displays on that TextBox. Please see the image below.
Is it possible to have the MenuPrice displayed on that TextBox? I have done this code but I dont think this is right.
private void menuDataGrid_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) //this code triggers when I dragged an item from datagridview to listbox.
{
menuDataGrid.DoDragDrop(menuDataGrid.CurrentRow.Cells[3].Value.ToString(), DragDropEffects.Copy);
}
private void menuListBox_SelectedValueChanged(object sender, EventArgs e) //this is the code when I select an item on the listview, then appears at the textbox
{
pricetxtbox.Text = menuListBox.SelectedItem.ToString();
}
private void ShowDataToGrid() //datagrid code
{
db_connection();
MySqlDataAdapter datagrid = new MySqlDataAdapter();
string selectAll = "SELECT * FROM Menu";
datagrid.SelectCommand = new MySqlCommand(selectAll, connect);
DataTable tbl = new DataTable();
datagrid.Fill(tbl);
BindingSource bs = new BindingSource();
bs.DataSource = tbl;
menuDataGrid.DataSource = bs;
menuDataGrid.Columns[6].Visible = false;
menuDataGrid.Columns[7].Visible = false;
}
I'm going to assume that the MenuPrice is also present on the GridView at a different cell, say Cells[4].
Then you can do something like this
private void menuListBox_SelectedValueChanged(object sender, EventArgs e) //this is the code when I select an item on the listview, then appears at the textbox
{
foreach (DataGridViewRow row in menuDataGrid.Rows)
{
if (row.Cells[3].Value.ToString().Equals(menuListBox.SelectedItem.ToString()))
{
pricetxtbox.Text = row.Cells[4].Value.ToString();
break;
}
}
}
You should pack your data into an object class with properties you want to display and hold. For example:
public class MenuItem()
{
public float MenuPrice { get; set; }
public string MenuCode { get; set; }
}
If you store data of type MenuItem in your ListView, you will be able to do:
private void menuListBox_SelectedValueChanged(object sender, EventArgs e) textbox
{
var item = menu.ListBoxItem.SelectedItem as MenuItem;
if(item == null) return;
pricetxtbox.Text = item.MenuPrice;
}
This would be one way to do it, if you want to enhance your code you should probably consider using databinding for you textboxes.

Combobox not showing items? winforms

Can any of you on stackoverflow explain me how come my combobox is not displaying any items. I have a combobox that get values from another so it only shows specific items, in this case the items are seat rows. I have tried to set a breakpoit and see if its null, and its not it gets the right value. But for some reason the combobox dont display the items ? can any of you help me.
Here is the first combobox selectIndex event:
private void cbBookedSeatMovDate_SelectedIndexChanged(object sender, EventArgs e)
{
ServiceReferenceMovieRunTime.MovieRunTimeServiceClient movRunService = new ServiceReferenceMovieRunTime.MovieRunTimeServiceClient();
string _selectedMovName = Convert.ToString(cbBookedSeatMovInfo.SelectedValue);
string _selectedMovDate = Convert.ToString(cbBookedSeatMovDate.SelectedValue);
cbBookedSeatMovTime.DataSource = movRunService.GetRunTimeOnMovNameAndDate(_selectedMovName, _selectedMovDate);
cbBookedSeatMovTime.ValueMember = "id";
cbBookedSeatMovTime.DisplayMember = "startTime";
}
and here is the combobox event thats not working right:
private void cbBookedSeatMovTime_SelectedIndexChanged(object sender, EventArgs e)
{
ServiceReferenceMovieRunTime.MovieRunTimeServiceClient movRunService = new ServiceReferenceMovieRunTime.MovieRunTimeServiceClient();
ServiceReferenceSeats.SeatsServiceClient seatService = new ServiceReferenceSeats.SeatsServiceClient();
string _selectedMovTime = Convert.ToString(cbBookedSeatMovTime.SelectedValue);
string _selectedMovName = Convert.ToString(cbBookedSeatMovInfo.SelectedValue);
string _selectedMovDate = Convert.ToString(cbBookedSeatMovDate.SelectedValue);
string _runTimeId = Convert.ToString(movRunService.GetRunTimeOnNameDateAndTime(_selectedMovName, _selectedMovDate, _selectedMovTime));
cbRow1.DataSource = seatService.GetRowsOnRunTime(Convert.ToInt32(_runTimeId.First()));
cbRow1.ValueMember = "id";
cbRow1.DisplayMember = "rowId";
}
Here is the LINQ query:
public List<TheaterSeat> GetRowsOnRunTime(int RunTime)
{
var queryResult = (from x in db.TheaterSeats
where x.runTime == RunTime
select x);
return queryResult.ToList();
}
Hope you guys can help me out!

Listbox bindind from another listbox

i have two list boxes in my form and a button in between these two boxes. In the first box i binded some data from the database and from this list box i have to select the items and should display those selected items in the second list box. this should happen when i click a button.i used the following code.i used a hash table.
private void btnCATAdd_Click(object sender, EventArgs e)
{
Hashtable ht = new Hashtable();
ht.Add(lbCATallSubcat.SelectedValue.ToString(),
lbCATallSubcat.Text.ToString());
int i = 0;
foreach (string ent in ht.Values)
{
string[] name = new string[lbCATallSubcat.Items.Count];
for (i = 0; i < lbCATallSubcat.SelectedItems.Count; i++)
{
name[i] = lbCATallSubcat.Text;
this.lbCATSelectedSubcat.Items.Add(name[i]);
}
lbCATSelectedSubcat.DisplayMember = ht.Values.ToString();
lbCATSelectedSubcat.ValueMember = ht.Keys.ToString();
}
}
well its working fine when im selecting only single item in the first list box but im unable to display when more than one item is selectd from the first list box
You should use SelectedItems property on that listbox instead SelectedValue. Currently your Hashtable contains only one element.
See http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.selecteditems.aspx
Add all selected value in hashtable using loop
private void btnCATAdd_Click(object sender, EventArgs e)
{
Hashtable ht = new Hashtable();
for(int i=0;i<lbCATallSubcat.Items.Count;i++)
{
if(ht.items[i].Selected)
{
ht.Add(lbCATallSubcat.Items[i].Value.ToString(),
lbCATallSubcat.Items[i].Text.ToString());
}
}
i = 0;
foreach (string ent in ht.Values)
{
string[] name = new string[lbCATallSubcat.Items.Count];
for (i = 0; i < lbCATallSubcat.SelectedItems.Count; i++)
{
name[i] = lbCATallSubcat.Text;
this.lbCATSelectedSubcat.Items.Add(name[i]);
}
lbCATSelectedSubcat.DisplayMember = ht.Values.ToString();
lbCATSelectedSubcat.ValueMember = ht.Keys.ToString();
}
}
Do you need the Hashtable? With LINQ, you can do something like:
public ObjHoldingData
{
public Display { get; set; }
public Value { get; set; }
}
public class Form
{
Form()
{
var dataList = new List<ObjHoldingData>();
//TODO: Fill list with all the data you pulled
Listbox1.Datasource = dataList;
Listbox1.DisplayMember = "Display";
Listbox1.ValueMember = "Value";
}
protected void ButtonClick()
{
Listbox2.Datasource = Listbox1.SelectedItems.Cast<ObjHoldingData>().ToList();
Listbox2.DisplayMember = "Display";
Listbox2.ValueMember = "Value";
}
}
If you still need the Hashtable you can do this at the start of the button click:
var ht = new Hashtable(ListBox1.SelectedItems.Cast<ObjHoldingData>().ToDictionary(o => o.Display, o => o.Value));

DataGridView ComboBox Column: Change cell value after selection from dropdown is made?

I have setup a ComboBoxColumn for my DataGridView and set its selectable values from an enumeration. It mostly works as I would like with the following exception.
Whenever I click the dropdown arrow and then select one of the enum values, it remains in sort of a "intermediate" state where the CellValueChanged event isn't triggered. I need to focus on another cell or another control for the event to fire.
I also have an event handler for the DataGridView's Leaving event which "validates" the contents by making sure that no cell is empty.
So, if I create a row and fill all the cells and come to the (currently blank) ComboBox column, change it to a value, and then click a Run button; my error dialog pops up because the ComboBox selection wasn't "saved".
How can I get around this? Is there a way that after I select a value from the drop down it automatically "sets" the value?
Thanks!
You should use CurrentCellDirtyStateChanged event and force a commit edit on the grid:
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
Hope it helps!
I would extend Moop's answer by checking the cell type instead of the column type.
dataGridView1.CurrentCellDirtyStateChanged += dataGridView1_CurrentCellDirtyStateChanged;
void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (CurrentCell is DataGridViewComboBoxCell)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
dataGridView1.EndEdit();
}
}
I would extend ionden's answer by checking if the DataGridViewColumn is the type of DataGridViewComboBoxColumn before forcing the CommitEdit. This will prevent other DataGridViewColumn objects from committing too early.
dataGridView1.CurrentCellDirtyStateChanged += dataGridView1_CurrentCellDirtyStateChanged;
void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
DataGridViewColumn col = dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex];
if (col is DataGridViewComboBoxColumn)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
The CurrentCellDirtyStateChanged event fixed mouse interaction for this issue, but it breaks keyboard interaction - using F4 then up/down arrow, every arrow click results in a dirty state change and commits the edit. The solution I found, was to grab the "DataGridViewComboBoxEditingControl" when it's created, and attach a DropDownClosed event to it. This works for keyboard and mouse interaction. In this example, we extended DataGridView so every instance would inherit this functionality:
protected override void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e)
{
DataGridViewComboBoxEditingControl control = e.Control as DataGridViewComboBoxEditingControl;
if (control != null)
{
control.DropDownClosed -= ComboBoxDropDownClosedEvent;
control.DropDownClosed += ComboBoxDropDownClosedEvent;
}
base.OnEditingControlShowing(e);
}
void ComboBoxDropDownClosedEvent(object sender, EventArgs e)
{
DataGridViewComboBoxCell cell = CurrentCell as DataGridViewComboBoxCell;
if ((cell != null) && cell.IsInEditMode)
{
CommitEdit(DataGridViewDataErrorContexts.Commit);
EndEdit();
}
}
In some cases, the value won't stick until the focus has left the row entirely. In that case, the only way to force the current edit to end is to end it on the whole binding context:
mGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
mGridView.BindingContext[mGridView.DataSource].EndCurrentEdit(); // <<===
I found this tip here.
I spend like two hours searching for an error because I did not notice that the cell value does not get saved if it´s not defocused, or better to say I just noticed that the cell is not defocused because the combobox whited out while saving(btn event).
Not only that, the EditOnEnter-Mode prevails that most other methods shown above work. The reason to use EditOnEnter is that when you use a DataGridViewComboBoxColumn, you have to click two times to open the dropdown if you do not set EditMode to EditOnEnter.
this.dataGridView.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
this.dataGridView.EndEdit();
this.dataGridView.EditMode = DataGridViewEditMode.EditOnEnter;
I hope this helps. It cost me around two hours wondering why the value in the object is not the same then shown on the GUI.
I am adding my answer as a follow-up to the discussion that has already occurred. I was trying to build a DataGridView that had different comboboxes per row. They also had to be responsive to a single click. And, when the selection was made, another cell in the row needed to be changed according to the combobox selection. The change needed to happen as soon as the selection was made. My main problem, like the OP's, was the change wouldn't happen until the combobox lost focus.
So, here is a full working minimal example of such a DataGridView. I had to bring it down to a minimum because getting all my requirements to work at the same time was tricky. Several SO posts went into making this, and I will update my post with references later. But for now, here goes...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace TestDGV
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Panel panel2;
private DataGridView TestGrid;
private void InitializeComponent()
{
this.panel2 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel2
//
this.panel2.Dock = DockStyle.Fill;
this.panel2.Name = "panel2";
this.panel2.TabIndex = 1;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(661, 407);
this.Controls.Add(this.panel2);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
private void Form1_Load(object sender, EventArgs e)
{
//basic grid properties
TestGrid = new DataGridView();
TestGrid.Dock = DockStyle.Fill;
TestGrid.AutoGenerateColumns = false;
TestGrid.Name = "TestGrid";
TestGrid.ReadOnly = false;
TestGrid.EditMode = DataGridViewEditMode.EditOnEnter;
//Event handlers
TestGrid.DataBindingComplete += TestGrid_DataBindingComplete;
TestGrid.CurrentCellDirtyStateChanged += TestGrid_CurrentCellDirtyStateChanged;
TestGrid.CellValueChanged += TestGrid_CellValueChanged;
//columns
var textCol = new DataGridViewTextBoxColumn();
textCol.HeaderText = "Text";
textCol.Name = "Text";
textCol.DataPropertyName = "Text";
textCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
TestGrid.Columns.Add(textCol);
var comboCol = new DataGridViewComboBoxColumn();
comboCol.HeaderText = "ComboBox";
comboCol.Name = "ComboBox";
comboCol.AutoComplete = true;
comboCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
TestGrid.Columns.Add(comboCol);
var resultCol = new DataGridViewTextBoxColumn();
resultCol.HeaderText = "Result";
resultCol.Name = "Result";
resultCol.DataPropertyName = "Result";
resultCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
TestGrid.Columns.Add(resultCol);
//Bind the data
Datum.TestLoad();
TestGrid.DataSource = Datum.Data;
panel2.Controls.Add(TestGrid);
}
void TestGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0 || e.ColumnIndex < 0)
return;
var row = TestGrid.Rows[e.RowIndex];
var cell = row.Cells[e.ColumnIndex];
if (cell is DataGridViewComboBoxCell)
{
var val = cell.Value as string;
var datum = row.DataBoundItem as Datum;
datum.Current = val;
row.Cells["Result"].Value = datum.Result;
TestGrid.InvalidateRow(e.RowIndex);
}
}
void TestGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if(TestGrid.CurrentCell is DataGridViewComboBoxCell)
{
TestGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
TestGrid.EndEdit();
}
}
void TestGrid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
foreach (DataGridViewRow row in TestGrid.Rows)
{
var datum = row.DataBoundItem as Datum;
if (datum == null)
return;
var cell = row.Cells["ComboBox"] as DataGridViewComboBoxCell;
if (cell.DataSource == null)
{
cell.DisplayMember = "KeyDisplayValue";
cell.ValueMember = "KeyValue";
cell.DataSource = (row.DataBoundItem as Datum).Combo;
cell.Value = (row.DataBoundItem as Datum).Current;
}
}
TestGrid.DataBindingComplete -= TestGrid_DataBindingComplete;
}
public class Datum
{
public static void TestLoad()
{
var t1 = new Triplet[] {
new Triplet("1", "World", "Everyone" ),
new Triplet("2", "Charlie", "Friend of Algernon" ),
new Triplet("3", "Lester", "Phenomenal programmer" ),
};
var t2 = new Triplet[] {
new Triplet("1", "World", "Everyone" ),
new Triplet("4", "Mary", "Wife of George Bailey" ),
new Triplet("3", "Lester", "Phenomenal programmer" ),
};
Data.Add(new Datum("hello, ", t1.ToList()));
Data.Add(new Datum("g'bye, ", t2.ToList()));
}
public static List<Datum> Data = new List<Datum>();
public Datum(string text, List<Triplet> combo)
{
this._text = text;
this._combo = combo.ToDictionary<Triplet,string>(o => o.KeyValue);
this.Current = combo[0].KeyValue;
}
private string _text;
public string Text
{
get
{
return _text;
}
}
private Dictionary<string, Triplet> _combo;
public List<Triplet> Combo
{
get
{
return _combo.Values.ToList();
}
}
private string _result;
public string Result
{
get
{
return _result;
}
}
private string _current;
public string Current
{
get
{
return _current;
}
set
{
if (value != null && _combo.ContainsKey(value))
{
_current = value;
_result = _combo[value].Description;
}
}
}
}
public class Triplet
{
public string KeyValue { get; set; }
public string KeyDisplayValue { get; set; }
public string Description { get; set; }
public Triplet(string keyValue, string keyDisplayValue, string description)
{
KeyValue = keyValue;
KeyDisplayValue = keyDisplayValue;
Description = description;
}
}
}
}
Thanks to Droj for the tip about EndCurrentEdit, which I needed to make it work for me.
This is what I ended up doing to instantly commit DataGridViewComboBoxColumns and DataGridViewCheckBoxColumns:
private void dataGridViewEnumerable_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
var dataGridView = sender as DataGridView;
if (dataGridView == null || dataGridView.CurrentCell == null)
return;
var isComboBox = dataGridView.CurrentCell is DataGridViewComboBoxCell;
if ((isComboBox || dataGridView.CurrentCell is DataGridViewCheckBoxCell)
&& dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit)
&& isComboBox && dataGridView.EndEdit())
dataGridView.BindingContext[dataGridView.DataSource].EndCurrentEdit();
}
Here's how I solved the issue
Private Sub dgvEcheancier_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dgvEcheancier.CurrentCellDirtyStateChanged
nbreClick += 1
With dgvEcheancier
Select Case .CurrentCell.ColumnIndex
Case 9
Dim col As DataGridViewComboBoxColumn = .Columns(9)
If TypeOf (col) Is DataGridViewComboBoxColumn Then
dgvEcheancier.CommitEdit(DataGridViewDataErrorContexts.Commit)
If nbreClick = 2 Then
MessageBox.Show("y" & "val=" & .CurrentCell.Value)
nbreClick = 0
End If
End If
End Select
End With
void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
dataGridView1.BeginEdit(true);
ComboBox cmbMiCtrl=(ComboBox)dataGridView1.EditingControl;
string Valor= cmbMiCtrl.Text;
dataGridView1.EndEdit();
}
One problem that I saw : It won't work if you choose :
GridView.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter;
You should use CellValueChanged which fires the change event on grid and inside the event you should commit changes and leave the control in order to save the item after it is selected.
private void FilterdataGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
FilterdataGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
FilterdataGrid.EndEdit(DataGridViewDataErrorContexts.LeaveControl);
}
Hope it helps!

Categories

Resources