c# datagrid combobox getvalue selected - c#

I have a datagrid with a combobox, i want to get my value, i can get it but i dont know why, i get it 4 times ???
could someone help me ?
here my code :
private void dgvLocataire_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
dgvLocataire.BeginEdit(false);
var ec = dgvLocataire.EditingControl as DataGridViewComboBoxEditingControl;
if (ec != null && ec.Width - e.X < SystemInformation.VerticalScrollBarWidth)
ec.DroppedDown = true;
if ((e.ColumnIndex != 3) && (e.ColumnIndex != 4))
{
dgvLocataire.Columns[e.ColumnIndex].ReadOnly = true;
}
dgvLocataire.CellValueChanged +=
new DataGridViewCellEventHandler(dgvLocataire_CellValueChanged);
//dgvLocataire.CurrentCellDirtyStateChanged +=
//new EventHandler(dgvLocataire_CurrentCellDirtyStateChanged);
}
private void dgvLocataire_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
dgvLocataire.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgvLocataire_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
string comboboxSelectedValue = string.Empty;
if (dgvLocataire.Columns[e.ColumnIndex].GetType() == typeof(DataGridViewComboBoxColumn))
comboboxSelectedValue = dgvLocataire.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
MessageBox.Show(comboboxSelectedValue);
}
The messagebox appears 4 times when i choose a value in combobox.
Thanks for your help

In dgvLocataire_CellMouseClick method, you are subscribing to dgvLocataire_CellValueChanged every time you click. Which means it can be called multiple times => MessageBox.Show(comboboxSelectedValue) is called multiple times.
You should subscribe to this event only once at the initialization of this form.

I change like this
private void dgvLocataire_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
dgvLocataire.BeginEdit(false);
var ec = dgvLocataire.EditingControl as DataGridViewComboBoxEditingControl;
if (ec != null && ec.Width - e.X < SystemInformation.VerticalScrollBarWidth)
ec.DroppedDown = true;
if ((e.ColumnIndex != 3) && (e.ColumnIndex != 4))
{
dgvLocataire.Columns[e.ColumnIndex].ReadOnly = true;
}
}
private void dgvLocataire_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox cb = e.Control as ComboBox;
if (cb != null)
{
cb.SelectionChangeCommitted -= new EventHandler(ComboBox_SelectedIndexChanged);
// now attach the event handler
cb.SelectionChangeCommitted += new EventHandler(ComboBox_SelectedIndexChanged);
}
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cb = (ComboBox)sender;
string item = cb.Text;
if (item != null)
MessageBox.Show(item);
}
`
but now i dont get the messagebox to show ???
any help ?
Thanks

Related

How to allow only numbers in specific cell while editing using Winform

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.KeyPress -= new KeyPressEventHandler(polNumDataGridViewTextBoxColumn_KeyPress);
if (dataGridView1.CurrentCell.ColumnIndex == 3) //Desired Column
{
TextBox tb = e.Control as TextBox;
if (tb != null)
{
tb.KeyPress += new KeyPressEventHandler(polNumDataGridViewTextBoxColumn_KeyPress);
}
}
}
private void polNumDataGridViewTextBoxColumn_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
The control in the gridview is not a TextBox. It is a DataGridViewTextBoxEditingControl
I made this working test (my control names and column indexes are different):
private void DataGridView2_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is DataGridViewTextBoxEditingControl tb) {
tb.KeyPress -= Tb_KeyPress;
tb.KeyPress += Tb_KeyPress;
}
}
private void Tb_KeyPress(object sender, KeyPressEventArgs e)
{
if (dataGridView2.CurrentCell.ColumnIndex == 1 &&
!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
But using data binding is usually the better approach and it fixes the problem automatically. I.e. when a cell is bound to numeric property or DateTime property is behaves accordingly.

Check input of DataGridView cell while writing

How to check if DataGridView cell contain number between 0 and 3 while entering value?
This is how I check if specific cell constains int number:
private void dgUpitnik_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.KeyPress -= new KeyPressEventHandler(ColumnOcjena_KeyPress);
if (dgUpitnik.CurrentCell.ColumnIndex == 2) //Desired Column
{
TextBox tb = e.Control as TextBox;
if (tb != null)
{
tb.KeyPress += new KeyPressEventHandler(ColumnOcjena_KeyPress);
}
}
}
private void ColumnOcjena_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
But how to check inside KeyPress event that the number entered in cell is 0, 1, 2 or 3?
I've found solution, here it is:
private void dgUpitnik_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
dgUpitnik.Rows[e.RowIndex].ErrorText = "";
int newInteger;
if (e.ColumnIndex == 2)
{
if (dgUpitnik.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
{
if (!int.TryParse(e.FormattedValue.ToString(), out newInteger) || newInteger > 3)
{
e.Cancel = true;
dgUpitnik.Rows[e.RowIndex].ErrorText = "Ocjena mora biti u rasponu od 0 do 3!";
}
}
}
}
Maybe it will be usable for someone someday.

C# WPF Focus previous textBox if current erased

I've a project where I need to focus previous field if current one is empty but user keep deleting. Like when you type CD-Key somewhere. You have couple blocks with 4-5 symbols each. And if you erase 3rd textBox for example you will be forced back to the second textBox right after 3rd one become emprty.
if (textBox2.Text.Length == 0)
{
Keyboard.Focus(textBox1);
}
This code works fine but considering that I've another onfocus event so textBox2 become empty as soon as got focus and due to code above focus forcing back to the textBox1. So it's looped.
If I get it right I need to catch pressing the Delete button, right? But here is my problem goes. I don't know how to insert this code
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete)
{
if (textBox2.Text.Length == 0)
{
Keyboard.Focus(textBox1);
}
}
}
inside this function:
private void textBox2_TextChanged(object sender, TextChangedEventArgs e)
{
if (textBox2.Text.Length == 2)
{
Keyboard.Focus(textBox3);
}
// HERE I NEED SOMETHING LIKE ELSE IF (e.Key == Key.Delete) {...
}
Help me please.
UPD. I've tried one more solution but it doesn't work:
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete)
{
if (textBox2.Text.Length == 0)
{
Keyboard.Focus(textBox1);
}
}
}
Here is the generic soution for arbitrary amount of TextBox'es.
The initialization of the TextBox'es list:
private readonly List<TextBox> _textBoxes;
public MainWindow()
{
InitializeComponent();
_textBoxes = new List<TextBox> { _textBox1, _textBox2, _textBox3 };
}
The version with KeyUp event:
private void TextBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab)
return;
var current = (TextBox)sender;
if (current.Text.Any())
return;
var index = _textBoxes.IndexOf(current);
if (index == 0)
return;
var previous = _textBoxes[index - 1];
previous.Focus();
previous.CaretIndex = previous.Text.Length;
}
The above version dissalows to jump through TextBox'es in press and hold scenario. To get around this, use TextChanged event:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var current = (TextBox)sender;
if (current.Text.Any())
return;
var index = _textBoxes.IndexOf(current);
if (index == 0)
return;
var previous = _textBoxes[index - 1];
previous.Focus();
previous.CaretIndex = previous.Text.Length;
}
Third solution with PreviewKeyDown that supports only Key.Delete:
private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key != Key.Delete)
return;
var current = (TextBox)sender;
if (current.Text.Length != 0)
return;
var index = _textBoxes.IndexOf(current);
if (index == 0)
return;
var previous = _textBoxes[index - 1];
previous.Focus();
previous.CaretIndex = 0;
}
Fourth solution also with PreviewKeyDown that supports both Key.Delete and Key.Back:
private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key != Key.Delete && e.Key != Key.Back)
return;
var current = (TextBox)sender;
if (current.Text.Length != 0)
return;
var index = _textBoxes.IndexOf(current);
if (index == 0)
return;
var previous = _textBoxes[index - 1];
previous.Focus();
if (e.Key == Key.Delete)
previous.CaretIndex = 0;
}
Finally. This one works:
private void textBox2_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete)
{
if (textBox2.Text.Length == 0)
{
Keyboard.Focus(textBox1);
}
}
}
This is not tested but should also work.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (textBox2.Text == "")
{
textBox1.Focus();
}
}
private void textBox3_KeyDown(object sender, KeyEventArgs e)
{
if (textBox3.Text == "")
{
textBox2.Focus();
}
}
}

How to add an event for a ComboCoxColumn cell being changed

I have a DataGridView, with several ComboBoxColumns in it. Is there a way to create an event, so that each time a ComboBoxColumncell is entered and an item selected, the event fires?
All I can figure out so far is this:
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0)
{
MessageBox.Show("Amanda");
}
}
Which is not doing anything.
You're probably looking for the EditingControlShowing event.
See here for a similar question:
"SelectedIndexChanged" event in ComboBoxColumn on Datagridview
try this one.
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox nameComboBox = e.Control as ComboBox;
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
if (nameComboBox != null)
{
((ComboBox)e.Control).DropDownStyle = ComboBoxStyle.DropDown;
((ComboBox)e.Control).AutoCompleteSource = AutoCompleteSource.ListItems;
((ComboBox)e.Control).AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
nameComboBox .SelectedIndexChanged -= (nameComboBox _SelectedIndexChanged);
nameComboBox .SelectedIndexChanged += (nameComboBox _SelectedIndexChanged);
}
}
}
private void nameComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == 1)
{
var rowindex = dataGridView1.CurrentCell.RowIndex;
if (dataGridView1[1, rowindex].EditedFormattedValue != null)
{
Consol.WriteLine(dataGridView1[1, rowindex].EditedFormattedValue.ToString());
}
else
{
//No value in cell
}
}
}

Cut, Copy, and paste in C#?

I have a lot of textboxes. I have a button that will cut the selected text of the Focused textbox. How do i do that? I have tried this:
if (((TextBox)(pictureBox1.Controls[0])).SelectionLength > 0)
{
((TextBox)(pictureBox1.Controls[0])).Cut();
}
Hope it is WinForms
var textboxes = (from textbox in this.Controls.OfType<TextBox>()
where textbox.SelectedText != string.Empty
select textbox).FirstOrDefault();
if (textboxes != null)
{
textboxes.Cut();
}
Loop through the controls to find the one with selected text:
foreach (Control x in this.PictureBox1.Controls)
{
if (x is TextBox)
{
if (((TextBox)x).SelectionLength > 0)
{
((TextBox)(x).Cut(); // Or some other method to get the text.
}
}
}
Hope this helps!
Try using common Enter and Leave events to set the last TextBox that had Focus.
private void textBox_Enter(object sender, EventArgs e)
{
focusedTextBox = null;
}
private void textBox_Leave(object sender, EventArgs e)
{
focusedTextBox = (TextBox)sender;
}
private void button1_Click(object sender, EventArgs e)
{
if (!(focusedTextBox == null))
{
if (focusedTextBox.SelectionLength > 0)
{
Clipboard.SetText(focusedTextBox.SelectedText);
focusedTextBox.SelectedText = "";
focusedTextBox = null;
}
}
}

Categories

Resources