Change ComboBox Enabled State based on the in another ComboBox C# - c#

I have two ComboBoxs 1st with CmdGuarantor and the 2nd with CmdGuarantorClass as names.
CmdGuarantor has a list of 7 items:
NSSF Private MOH Army IS GS UNHCR while CmdGuranatorClass has 1st Class 2nd Class 3rd Class in its items list.
I want to disable CmdGuarantorClass whenever CmdGuarator.SelectedItem.ToString() == "Private" || CmdGuarator.SelectedItem.ToString() == "UNCHR"
how can I accomplish that?
P.S.: I tried using the EnableChanged event on CmdGuarantorClass ComboBox using this method
private void ComboBox2_EnabledChanged(object sender, EventArgs e)
{
if (CmdGuarantor.SelectedItem.ToString() == "Private" || CmdGuarantor.SelectedItem.ToString() == "UNCHR")
{
CmdGuarantorClass.Enabled = false;
}
else CmdGuarantorClass.Enabled = true;
}
but with no luck.
thank you in advance.

You should be listening for the SelectedIndexChanged event, not the EnabledChanged event. EnabledChanged is only raised when the Enabled property is changed.

Assuming the datagridview tag is a mistake and you are talking about two different winform ComboBoxes… then… I suggest you wire up the first combo boxes SelectedIndexChanged event.
This event will fire when the user changes the selection in the combo box. In that event you can check the combo box values as you have done and then set the other combo boxes Enabled property as needed. Something like…
private void comboGuarantor_SelectedIndexChanged(object sender, EventArgs e) {
if (comboGuarantor.SelectedItem.ToString() == "Private" ||
comboGuarantor.SelectedItem.ToString() == "UNCHR") {
comboGuarantorClass.SelectedIndex = -1;
comboGuarantorClass.Enabled = false;
}
else {
comboGuarantorClass.Enabled = true;
}
}

Related

Disable Command button until comboBox value is selected

I have a comboBox (cmbPortName) and a command button (btnConnect).
You'd use the drop-down in the comboBox to select a port you want to connect to and then click btnConnect.
I just want to disable the command button till a valid selection is made in ComboBox. I figured the best way to solve this by doing something like
btnConnect.Enabled = True;
until a selection is made in the Combobox.
Is there a better way of doing it? I am quite new to the programming and still learning stuffs.
You need to add a SelectedIndexChanged event handler for the combo box. In the Visual Studio design view for your form, double-click the combo box, or double-click the empty space to the right of the event name in the "Properties" window:
That will generate and bring you to this block of code in your form's .cs file:
private void cmbPortName_SelectedIndexChanged(object sender, EventArgs e)
{
}
And then add whatever code you want to conditionally enable your button:
private void cmbPortName_SelectedIndexChanged(object sender, EventArgs e)
{
// This will enable the button so long as the selected value
// is not null or an empty string.
if (cmbPortName.SelectedItem != null && !string.IsNullOrEmpty(cmbPortName.SelectedItem.ToString()))
btnConnect.Enabled = true;
else
btnConnect.Enabled = false;
}
Disable the button at first.
if(cmbPortName.SelectedIndex > 0)
{
btnConnect.Enabled = True;
}
There is an event for the combobox selected item change, you can write btnConnect.Enabled = True there.

How get Event "item Selected" with AutoComplete in C#?

I have code using an AutoCompleteStringCollection:
private void txtS_TextChanged(object sender, EventArgs e)
{
TextBox t = sender as TextBox;
string[] arr = this.dbService.GetAll();
if (t != null)
{
if (t.Text.Length >= 3)
{
AutoCompleteStringCollection collection = new AutoCompleteStringCollection();
collection.AddRange(arr);
this.txtSerial.AutoCompleteCustomSource = collection;
}
}
}
How can I get the event for "item selected" after user selects an AutoComplete suggestion? And value of field?
There's no such thing as chosen item Event for a textBox, which I believe you're using for the AutoComplete. What you could do is add a key down event to your textBox. There you could verify if the enter key was pressed (clicking on a suggested link is the same as pressing enter). Something like that:
private void textBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData == Keys.Enter) {
String selItem = this.textBox1.Text;
}
}
Rather than focusing on detecting if an item from the autocomplete list was selected, instead you should check if the current value of the textbox is in the set of autocomplete entries.
if (txtSerial.AutoCompleteCustomSource.Contains(t.Text))
{
// Logic to handle an exact match being selected
...
}
else
{
// Update the autocomplete entries based on what was typed in
}
If the user typed in an exact string which happens to be be within the list of autocomplete values -- OR -- they select that value from the autocomplete list -- should this produce any different behavior? I think that in most cases it should not.
Short answer: make a custom event
Long answer:
You can intercept the KeyDown event of your textbox for numpad Enter or normal Enter and the mouse doubleclick event of the toolbox and compare the content of the toolbox then fire an event if they match that a delegate will pick up.
It depends a bit on the situation and workflow of your program but I have an example where I trigger the check on focuslost of the combobox. And then I check if the selected value is part of the collection:
private void cmbt1Name1_LostFocus(object sender, RoutedEventArgs e)
{
ComboBox cmb = sender as ComboBox;
FillFivePoints(cmb);
}
private void FillFivePoints(ComboBox usedCombobox)
{
if (txtSerial.AutoCompleteCustomSource.Contains(t.Text))
{
...

Radio button checked changed event fires twice

Please read my question its not a duplicate one.
I've three radio buttons on windows form and all these buttons have common 'CheckedChanged' event associated. When I click any of these radio buttons, it triggers the 'CheckedChanged' event twice.
Here is my code:
private void radioButtons_CheckedChanged(object sender, EventArgs e)
{
//My Code
}
I inserted the breakpoint and the whole code within this event iterates twice.
Please tell me why it is behaving like this?
As the other answerers rightly say, the event is fired twice because whenever one RadioButton within a group is checked another will be unchecked - therefore the checked changed event will fire twice.
To only do any work within this event for the RadioButton which has just been selected you can look at the sender object, doing something like this:
void radioButtons_CheckedChanged(object sender, EventArgs e)
{
RadioButton rb = sender as RadioButton;
if (rb != null)
{
if (rb.Checked)
{
// Only one radio button will be checked
Console.WriteLine("Changed: " + rb.Name);
}
}
}
To avoid it, just check if radioButton is checked
for example:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked)
//your code
}
CheckedChanged is raised whenever the Checked property changes. If you select a RadioButton then the previously selected RadioButton is unchecked (fired CheckedChanged), and then the new RadioButton is checked (fired CheckedChanged).
It's triggering once for the radio button transition from checked to unchecked, and again for the radio button transitioning from unchecked to checked (i.e. any change in checked state triggers the event)
You could set the AutoCheck property true for each RadioButton then catch the Click event instead of the CheckChanged event. This would ensure that only one event is fired, and the logic in the handler can cast the sender to type RadioButton if needed to process the click. Often the cast can be avoided if the handler logic is simple. Here is an example which handles three controls, rbTextNumeric, rbTextFixed and rbTextFromFile:
private void rbText_Click(object sender, EventArgs e)
{
flowLayoutPanelTextNumeric.Enabled = rbTextNumeric.Checked;
txtBoxTextFixed.Enabled = rbTextFixed.Checked;
flowLayoutPanelTextFromFile.Enabled = rbTextFromFile.Checked;
}
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
int click = 0;
private void radioButton1_Click(object sender, EventArgs e)
{
click++;
if (click %2==1)
{
radioButton1.Checked = true;
}
if (click %2==0)
{
radioButton1.Checked = false;
}
if (radioButton1.Checked==true)
{
label1.Text = "Cheked";
}
if (radioButton1.Checked==false)
{
label1.Text = "Uncheked";
}
}
}
}
The other answers are correct but miss the reason for the underlying problem.
When a radio button is checked the first event sent is the change from the unchecked item
however if you check its state by its control name you will still see its old checked status because the form has not been updated yet. To see its true status you need to cast the sender object.
This allows you to perform any actions relating to the condition which is being deselected should you need to do so.
In the not uncommon scenario below multiple radio buttons are sent to the same handler event.
Simply checking the state of the sender for checked will not work here as we need to perform different actions depending on which radio button has been pressed.
So first we ignore any sender that has just been unchecked.
then we identify the checked sender by control name to process the correct action.
private void ModeChangedExample(object sender, EventArgs e)
{
// multiple radio buttons come here
// We only want to process the checked item.
// if you need to something based on the item which was just unchecked don't use this technique.
// The state of the sender has not been updated yet in the form.
// so checking against rdo_A check state will still show it as checked even if it has just been unchecked
// only the sender variable is up to date at this point.
// To prevent processing the item which has just been uncheked
RadioButton RD = sender as RadioButton;
if (RD.Checked == false) return;
if (rdo_A.Name == RD.Name)
{
//Do stuff
}
if (rdo_B..Name == RD.Name)
{
// Do other stuff
}
if (rdo_C.Name == RD.Name)
{
// Do something else
}
}
This problem of double checking happens when there is a series of RadioButton Clicks in succession.I had this same problem.The last click will give two results.To overcome this i made a dummy click in the end.The double click stopped.Try this method.
Venkatraman

How do I get DataGridView comboboxes to display their drop down list in one click?

After I set "EditOnEnter" to be true, the DataGridViewComboBoxCell still takes two clicks to open if I don't click on the down arrow part of the combo box.
Anyone have any clue how to fix this? I've got my own DataGridView class that I use, so I can easily fix this issue system-wide with a few smart event handlers I hope.
Thanks.
Since you already have the DataGridView's EditMode property set to "EditOnEnter", you can just override its OnEditingControlShowing method to make sure the drop-down list is shown as soon as a combo box receives focus:
public class myDataGridView : DataGridView
{
protected override void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e)
{
base.OnEditingControlShowing(e);
if (e.Control is ComboBox) {
SendKeys.Send("{F4}");
}
}
}
Whenever an edit control in your DataGridView control gets the input focus, the above code checks to see if it is a combo box. If so, it virtually "presses" the F4 key, which causes the drop-down portion to expand (try it when any combo box has the focus!). It's a little bit of a hack, but it works like a charm.
I used this solution as it avoids sending keystrokes:
Override the OnCellClick method (if you're subclassing) or subscribe to the CellClick event (if you're altering the DGV from another object rather than as a subclass).
protected override void OnCellClick(DataGridViewCellEventArgs e)
{
// Normally the user would need to click a combo box cell once to
// activate it and then again to drop the list down--this is annoying for
// our purposes so let the user activate the drop-down with a single click.
if (e.ColumnIndex == this.Columns["YourDropDownColumnName"].Index
&& e.RowIndex >= 0
&& e.RowIndex <= this.Rows.Count)
{
this.CurrentCell = this[e.ColumnIndex, e.RowIndex];
this.BeginEdit(false);
ComboBox comboBox = this.EditingControl as ComboBox;
if (comboBox != null)
{
comboBox.DroppedDown = true;
}
}
base.OnCellContentClick(e);
}
protected override void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e)
{
base.OnEditingControlShowing(e);
DataGridViewComboBoxEditingControl dataGridViewComboBoxEditingControl = e.Control as DataGridViewComboBoxEditingControl;
if (dataGridViewComboBoxEditingControl != null)
{
dataGridViewComboBoxEditingControl.GotFocus += this.DataGridViewComboBoxEditingControl_GotFocus;
dataGridViewComboBoxEditingControl.Disposed += this.DataGridViewComboBoxEditingControl_Disposed;
}
}
private void DataGridViewComboBoxEditingControl_GotFocus(object sender, EventArgs e)
{
ComboBox comboBox = sender as ComboBox;
if (comboBox != null)
{
if (!comboBox.DroppedDown)
{
comboBox.DroppedDown = true;
}
}
}
private void DataGridViewComboBoxEditingControl_Disposed(object sender, EventArgs e)
{
Control control = sender as Control;
if (control != null)
{
control.GotFocus -= this.DataGridViewComboBoxEditingControl_GotFocus;
control.Disposed -= this.DataGridViewComboBoxEditingControl_Disposed;
}
}
To avoid the SendKeys issues, try the solution from Open dropdown(in a datagrid view) items on a single click. Essentially, in OnEditingControlShowing hook to the Enter event of the combo box, in the Enter event handler, set ComboBox.DroppedDown = true. That seems to have the same effect, but without the side effects #Cody Gray mentions.

How to prevent/cancel a combobox's value change in c#?

I have a combobox at the top of a form that loads editable data into fields below. If the user has made changes, but not saved, and tries to select a different option from the combobox, I want to warn them and give them a chance to cancel or save.
I am in need of a "BeforeValueChange" event with a cancelable event argument.
Any advice on how to accomplish?
Save the ComboBox's SelectedIndex when to box if first entered, and then restore it's value when you need to cancel the change.
cbx_Example.Enter += cbx_Example_Enter;
cbx_Example.SelectionChangeCommitted += cbx_Example_SelectionChangeCommitted;
...
private int prevExampleIndex = 0;
private void cbx_Example_Enter(object sender, EventArgs e)
{
prevExampleIndex = cbx_Example.SelectedIndex;
}
private void cbx_Example_SelectionChangeCommitted(object sender, EventArgs e)
{
// some custom flag to determine Edit mode
if (mode == FormModes.EDIT)
{
cbx_Example.SelectedIndex = prevExampleIndex;
}
}
Here is the simplest fix:-
bool isSelectionHandled = true;
void CmbBx_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (isSelectionHandled)
{
MessageBoxResult result = MessageBox.Show("Do you wish to continue selection change?", this.Title, MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.No)
{
ComboBox combo = (ComboBox)sender;
isSelectionHandled = false;
if (e.RemovedItems.Count > 0)
combo.SelectedItem = e.RemovedItems[0];
return;
}
}
isSelectionHandled = true;
}
Save the current value on the Enter event.
Implement the BeforeValueChange logic in the ValueChanged event, before the actual ValueChanged logic. If the user cancels, set the stored value and don't continue in the method (return).
If you're going to use this system a lot, I'd suggest inheriting ComboBox and implementing your BeforeValuechange event there.
The Validating event can be used for this scenario
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx
You don't get an appropriate event by default. You could cache the previous value and set it back to that if the user wants to cancel.
How about using the Validating / Validated events?
It works well, if the event happening on LostFocus instead of Change is ok with you.
Otherwise, how about
public void Combobox_ValueChanged(object sender, EventArgs e) {
if (!AskUserIfHeIsSureHeWantsToChangeTheValue())
{
// Set previous value
return;
}
// perform rest of onChange code
}
You could use a message filter to intercept clicks and key presses, which would allow you to prevent the combo box's normal behaviour. But I think you'd be better off disabling the combo box when the user makes a change, and require them to either save or revert their changes.
You can't really prevent it, but you can change it back to the old value if certain requirements aren't met:
private SomeObject = selectedSomeObject=null;
private void cbxTemplates_SelectionChangeCommitted(object sender, EventArgs e)
{
if (!(sender is ComboBox cb)) return;
if (!(cb.SelectedItem is SomeObject tem)) return;
if (MessageBox.Show("You sure?", "??.",
MessageBoxButtons.OKCancel) != DialogResult.OK)
cb.SelectedItem = selectedSomeObject;
else
{
selectedSomeObject = tem;
}
}

Categories

Resources