WinForms DatagridViewComboboxColumn "enter key" - c#

I have a datagridview with an editable combobox column, but everytime I press "Enter" on the current combobox, the text I'm writing disappears.
private void dgView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (dgView1.CurrentCell.IsInEditMode)
{
if (dgView1.CurrentCell.GetType() == typeof(DataGridViewComboBoxCell))
{
if (!((DataGridViewComboBoxColumn)dgView1.Columns[e.ColumnIndex]).Items.Contains(e.FormattedValue))
{
((DataGridViewComboBoxColumn)dgView1.Columns[e.ColumnIndex]).Items.Add(e.FormattedValue);
}
}
}
}
private void dgView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control.GetType() == typeof(DataGridViewComboBoxEditingControl))
{
ComboBox cbo = (ComboBox)e.Control;
cbo.DropDownStyle = ComboBoxStyle.DropDown;
}
}
I also tried adding the event handlers: "on key press", "on key down" and "on key up" but same problem happens.
How can I keep the current text when I press "Enter" key?

The DataGridViewComboBoxColumn does not accept any value which is not contained in the Items collection. So when user types in a new value, the current cell does simply not store the value after editing. You have to find another way to get the last value right after cell being edited. We can get the actual DataGridViewComboBoxEditingControl in the EditingControlShowing event handler, that control is actually a ComboBox, we can handle the TextChanged event. The best DataGridView event to handle to submit the new value (add to Items and show in the current cell) is the CellEndEdit event. So here is the code you should do, I've tested it and looks like it works as what you expected:
//use some variable to store the last edited value
string editingValue;
//EditingControlShowing event handler
private void dataGridView1_EidtingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e) {
var combo = e.Control as ComboBox;
if(combo != null){
combo.DropDownStyle = ComboBoxStyle.DropDown;
combo.TextChanged += (s,ev) => {
editingValue = combo.Text;
};
}
}
//CellEndEdit event handler for your dataGridView1
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e){
var comboColumn = dataGridView1.Columns[e.ColumnIndex] as DataGridViewComboBoxColumn;
if(comboColumn != null && editingValue != "" &&
!comboColumn.Items.Contains(editingValue)){
comboColumn.Items.Add(editingValue);
dataGridView1[e.ColumnIndex, e.RowIndex].Value = editingValue;
}
}
Note that the cell value is supposed to be string which is why the editingValue is declared as string, otherwise, you may have to convert the Text of the editing comboBox to the correct type of editingValue.

Related

How to change same combobox in datagridview multiple times in a row?

I have a combobox in a datagridview and on the first event handling it works fine, when i choose value from the combobox in the other row it also works fine but the problem is when i choose value from the same combobox in the same row two times. On the second event handling it doesn't go to the " dataGridView1_EditingControlShowing" method, it directly goes to "combo_SelectedIndexChanged" and it causes System.NullReferenceException: 'Object reference not set to an instance of an object.'
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
combo = e.Control as ComboBox;
if(combo != null)
{
combo.SelectedIndexChanged -= new EventHandler(combo_SelectedIndexChanged);
combo.SelectedIndexChanged += combo_SelectedIndexChanged;
}
}
public void combo_SelectedIndexChanged(object sender, EventArgs e)
{
selected = (sender as ComboBox).SelectedItem.ToString();
LoadData(selected);
}
You need to go to the form.designer.cs file and update the pointer for the combobox selectedindexchanged to point to dataGridView1_EditingControlShowing
for example
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.dataGridView1_EditingControlShowing);

Reacting to a key pressed on a DataGridView new row, but not creating a row for it

I have a DataGridView where, if the user presses a key in the new row, I want to open an other window which knows about which key was pressed, but not to create the new row. I have seen that KeyDown and KeyPress events are ignored here; I can use RowsAdded, but the row gets added; or I can use CellBeginEdit and set e.Cancel=true, but then I can't access the pressed key. Any ideas on how to do this?
The KeyPress event is indeed what you want.
It is not ignored by the DataGridView, but it is handled by the TextBox that takes care of the user input.
So you need to catch it there.
Here is an example:
TextBox editTB = null; // a class level variable to hold the reference
// here we get the reference to the editing control
// other control types will work as well..
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is TextBox)
{
editTB = (TextBox)e.Control;
editTB.KeyPress -= editTB_KeyPress;
editTB.KeyPress += editTB_KeyPress;
}
}
void editTB_KeyPress(object sender, KeyPressEventArgs e)
{
// use the checks you actually need..
if (e.KeyChar == '#')
{
// do your things..
Console.WriteLine("---->" + e.KeyChar);
e.Handled = true; // eat up the key event
}
}

Set the highlighted item in the comboBox's dropdown list as the current value on cell exit or cell leave

private void dataGridViewSales_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (this.dataGridViewSales.CurrentCell.ColumnIndex == 1)
{
ComboBox c = e.Control as ComboBox;
((ComboBox)c).AutoCompleteSource = AutoCompleteSource.ListItems;
((ComboBox)c).AutoCompleteMode = AutoCompleteMode.SuggestAppend;
((ComboBox)c).DropDownStyle = ComboBoxStyle.DropDown;
}
}
With the code above, am having a problem where by after making my selection from an auto complete combobox, i loose my selection when i exit the combobox Cell by pressing the Tab key. Some times, the selection is retained, other times the selection is cleared, it sort of happens randomly.
handling the CurrentCellDirtyStateChanged event resolved the issue, i hope it doesn't result into some other issue though!
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}

TextBox Example Into Datagridview

I have simple textbox example as below:
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = "Apple";
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Length == 1)
{
if (textBox1.Text == "B" || textBox1.Text == "b")
{
textBox1.Text = "Ball";
}
}
}
By default textbox1 should return "Apple" on Form load but when I press "b" or "B" then it should return "Ball" on textbox1. I have a confusion on utilize it into datagridview. how can i do it in datagridview?.
Suppose I have One column on datagridview like below:
private void Form1_Load(object sender, EventArgs e)
{
DataGridViewColumn Particulars = new DataGridViewTextBoxColumn();
dataGridView1.Columns.Insert(0, Particulars );
}
If I have above column In datagridview1 than How to do I with datagridview1 which I have did with textbox?.
You might find it more straightforward to use the auto-complete functionality built-in to the textbox control, rather than trying to code for all possible scenarios yourself.
There are two important properties of the TextBox control that you must configure to enable its auto-completion functionality: AutoCompleteMode and AutoCompleteSource.
The AutoCompleteMode property allows you to choose how the textbox autocomplete function will look in action. You can choose between any of the AutoCompleteMode values
None Disables the automatic completion feature for the ComboBox and TextBox controls.
Suggest Displays the auxiliary drop-down list associated with the edit control. This drop-down is populated with one or more suggested completion strings.
Append Appends the remainder of the most likely candidate string to the existing characters, highlighting the appended characters.
SuggestAppend Applies both Suggest and Append options.
The AutoCompleteSource property allows you to specify the strings that you want the textbox to propose auto-completion with. In your case, you will probably want to specify a CustomSource, which requires you to set the AutoCompleteCustomSource property to a user-defined collection of strings—something like "Apple, Ball, ..." etc.
The DataGridViewTextBoxColumn simply hosts a standard TextBox control, so all of the auto-complete functionality it provides is already available to you for free. You can set the appropriate properties of this textbox by handling the EditingControlShowing event of your DataGridView, like so:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
//Create and fill a list to use as the custom data source
var source = new AutoCompleteStringCollection();
source.AddRange(new string[] {"Apple", "Ball"});
//Set the appropriate properties on the textbox control
TextBox dgvEditBox = e.Control as TextBox;
if (dgvEditBox != null)
{
dgvEditBox.AutoCompleteMode = AutoCompleteMode.Suggest;
dgvEditBox.AutoCompleteCustomSource = source;
dgvEditBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
}
EDIT: If you'd prefer to keep the same behavior as you have in the original textbox example, you can just handle the TextChanged event for the DataGridViewTextBoxColumn. As I already explained above, the DataGridViewTextBoxColumn simply hosts a standard TextBox control, so it's fairly straightforward to add a handler for its TextChanged event and use the same code you had before:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
TextBox dgvEditBox = e.Control as TextBox;
if (dgvEditBox != null)
{
//Add a handler for the TextChanged event of the underlying TextBox control
dgvEditBox.TextChanged += new EventHandler(dgvEditBox_TextChanged);
}
}
private void dgvEditBox_TextChanged(object sender, EventArgs e)
{
//Extract the textbox control
TextBox dgvEditBox = (TextBox)sender;
//Insert the appropriate string
if (dgvEditBox.Text.Length == 1)
{
if (dgvEditBox.Text == "B" || dgvEditBox.Text == "b")
{
dgvEditBox.Text = "Ball";
}
}
}

OnClick event in WinForms DataGridView

I am using DataGridView in WinForms and by this piece of code I am assigning it columns and values
dataGrid.DataSource = sourceObject;
only by this line all the columns and values into the grid.
How do I handle the onClick event of a specific row or field. I want to do edit a particular item in the grid but I cannot find any way to send the id of an item from the event method.
There is class DataGridViewEventHandler which I do not understand?
I have also tried to add columns manually as a buttons but I did not find way to assign it action method onClick.
You cannot find "OnClick" event for cell inside DataGridView, as it does not exist. Have a look at MSDN Page for DataGridView Events provided for Cell Manipulation and Events
Here are some samples from MSDN, about the events which you may use
Sample CellMouseClick Event and Handler
private void DataGridView1_CellMouseClick(Object sender, DataGridViewCellMouseEventArgs e) {
System.Text.StringBuilder cellInformation = new System.Text.StringBuilder();
cellInformation .AppendFormat("{0} = {1}", "ColumnIndex", e.ColumnIndex );
cellInformation .AppendLine();
cellInformation .AppendFormat("{0} = {1}", "RowIndex", e.RowIndex );
cellInformation .AppendLine();
MessageBox.Show(cellInformation.ToString(), "CellMouseClick Event" );
}
Sample CellClick Event and Handler
private void dataGridView1_CellClick(object sender,
DataGridViewCellEventArgs e)
{
if (turn.Text.Equals(gameOverString)) { return; }
DataGridViewImageCell cell = (DataGridViewImageCell)
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
if (cell.Value == Play)
{
// PlaySomething()
}
else if (cell.Value == Sing)
{
// SingSomeThing();
}
else
{
MessagBox.Show("Please Choose Another Value");
}
}
Hope this helps
Here, you can see a list of events for the DataGridView. If you want to see if a cell has been clicked, you would want to consume the CellMouseclick event. In your code, you can handle the event like this:
private void DataGridView1_CellMouseClick(Object sender, DataGridViewCellMouseEventArgs e)
{
//Do something
}
To get specific details about the cell, then you can use the 'e' property mentioned above. It's of type DataGridViewCellMouseEventArgs. This will give you information about that specific cell. You can handle most of the other events, found in the first link, in the same way. (Not all the events will have DataGridViewCellMouseEventArgs as the argument, of course).

Categories