I'm writing a fairly simple application in which a user can select certain inputs and it processes data. I am having a problem in when a user selects a specific string from one of the combo-boxes, it doesn't disable other controls. Basically when the user selects the combo-box and selects 'Initiate' all other controls should be disabled.
private void cbalpha_SelectedIndexChanged(object sender, EventArgs e)
{
var operatorcheckbox = (CheckBox)sender;
foreach (Control cb in this.Controls)
if ((StringtDataChoiceorSelect.SelectedItem != "(Initiate)")
{
continue;
}
else
{
cb.Enabled = operatorcheckbox.Checked;
}
}
if you want to diable all the controls why are you using checkbox value to enable disable. It should be simply this
private void cbalpha_SelectedIndexChanged(object sender, EventArgs e)
{
bool isEnabled = string.Compare(StringtDataChoiceorSelect.SelectedItem.ToString(),"(Initiate)",StringComparison.OrdinalIgnoreCase) == 0;
foreach (Control cb in this.Controls)
cb.Enabled = !isEnabled ;
}
try
private void cbalpha_SelectedIndexChanged(object sender, EventArgs e)
{
var operatorcheckbox =(CheckBox)sender;
foreach (Control cb in this.Controls)
{
if ((StringtDataChoiceorSelect.SelectedItem != "(Initiate)")
{
if(!cb.Enabled)
{
cb.Enabled = true;
}
}
else
{
cb.Enabled = false;
}
}
}
on SelectedIndexChanged event check if the selected objected is same on which you want to disable other control and then disable it.
protected void ddltext_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlPerc.SelectedValue.Equals("0.01"))
{
txtbox.Enabled = false;
}
}
I'd use delegates and events for this.
if(operatorcheckbox.Checked &&
StringtDataChoiceorSelect.SelectedItem == "(Initiate)")
{
EventHandler -= checkboxdelegate;
}
else
EventHandler += checkboxdelegate;
You can add a method if there's controls you do not want to keep enabled.
Related
How can I make button property set to enabled=true after all my textboxes are not empty?
I'm learning programming and my apps are simple.
I know how to enable this property when one of my textboxes have text but this is not the case.
Use case is that user need to put data in both textboxes and after that will be able to click btn.
How in most simple way can I validate all form and then enable button?
There are just 2 tb:
https://i.imgur.com/JUslNWE.png
You need to create a TextBox_TextChanged event and subscribe to all text boxes.
private void TextBox_TextChanged(object sender, EventArgs e)
{
int notEmptyTextBoxCount = 0;
int textBoxCount = 0;
foreach (var item in Controls)
{
if (item is TextBox txtb)
{
textBoxCount++;
if (txtb.Text != String.Empty)
notEmptyTextBoxCount++;
}
}
if (textBoxCount == notEmptyTextBoxCount)
button.Enabled = true;
else
button.Enabled = false;
}
Thanks guys for all feedback.
I have managed to do this this way:
private void ValidateTextBoxes()
{
if (loginTextBox.Text.Length != 0 && passTextBox.Text.Length != 0)
{
generateHashBtn.Enabled = true;
}
else
{
generateHashBtn.Enabled = false;
}
}
private void TextBox1_TextChanged(object sender, EventArgs e)
{
ValidateTextBoxes();
}
private void TextBox2_TextChanged(object sender, EventArgs e)
{
ValidateTextBoxes();
}
Hello I was wondering how can I keep an eye on all textboxes in Form whether in any of them was changed value. I saw some code here
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
TextBox tb = (TextBox)ctrl;
tb.TextChanged += new EventHandler(tb_TextChanged);
}
}
}
void tb_TextChanged(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Tag = "CHANGED"; // or whatever
}
And a guy who wrote this code says that "it can't be assigned to textboxes in Panels and Grouboxes".
So my question is as I have almost every textbox in groubox or panel, how can I see whether change was made for textboxes in panels or groupbox?
You can make your method recursive:
private void Form1_Load(object sender, EventArgs e)
{
Assign(this);
}
void Assign(Control control)
{
foreach (Control ctrl in control.Controls)
{
if (ctrl is TextBox)
{
TextBox tb = (TextBox)ctrl;
tb.TextChanged += new EventHandler(tb_TextChanged);
}
else
{
Assign(ctrl);
}
}
}
void tb_TextChanged(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Tag = "CHANGED"; // or whatever
}
Just find a better name for the method instead of Assign.
When you have to deal with nested controls, 1 for loop can't help. You have to use some recursive method or custom stack to loop through all the controls, something like this:
private void RegisterTextChangedEventHandler(Control root){
Stack<Control> stack = new Stack<Control>();
stack.Push(root);
Control current = null;
while(stack.Count>0){
current = stack.Pop();
foreach(var c in current.Controls){
if(c is TextBox) ((TextBox)c).TextChanged += textChanged;
stack.Push(c);
}
}
}
private void textChanged(object sender, EventArgs e){
//....
}
//Use it
RegisterTextChangedEventHandler(yourForm);//Or your container ....
You need another loop for the groupbox and panels, you can use this code:
private void addEvents(Control.ControlCollection ct)
{
foreach (Control ctrl in ct)
{
if (ctrl is TextBox)
{
TextBox tb = (TextBox)ctrl;
tb.TextChanged += new EventHandler(tb_TextChanged);
}
else if (ctrl is GroupBox || ctrl is Panel) addEvents(ctrl.Controls);
}
}
private void Form1_Load(object sender, EventArgs e)
{
addEvents(this.Controls);
}
void tb_TextChanged(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Tag = "CHANGED"; // or whatever
}
I have a CheckedListBox with 10 items. On each item check a method is being called. I want to disable the checkbox of that particular item for which the method is being executed so that user cannot uncheck the item till the job is completed.
Note: Unchecking of an item calls another method.
Here is the code of ItemCheck Event:
private void host_listbox_ItemCheck(object sender, ItemCheckEventArgs e)
{
int index = e.Index;
try
{
string sitem = host_listbox.Items[index].ToString();
host_list[sitem].checked_event=e;
if (!host_list[sitem].is_busy)
{
host_config.listEnabled = false;
host_list[sitem].con_worker.RunWorkerAsync();
}
if (host_listbox.GetItemCheckState(index) == CheckState.Checked)
{
host_list[sitem].connected = false;
}
}
catch(Exception ex)
{
output_textbox.AppendText("connection failed!" +ex.ToString() +Environment.NewLine);
}
}
You can check/uncheck items in your checkedListBox with this code
checkedListBox.SetItemChecked(item, true);
for more informations go to microsoft documentation
private void host_listbox_ItemCheck(object sender, ItemCheckEventArgs e)
{
int index = e.Index;
try
{
string sitem = host_listbox.Items[index].ToString();
if (host_list[sitem].is_busy // or whatever indicates that background worker is running or any condition that specifies, that you do not want to let this item to be changed)
e.NewValue = e.CurrentValue; //Change the value back
else
{
//Let the checked state of the item change
This code prevent checked state change if associated background work is running:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
workerList = new List<BackgroundWorker>();
for (int i = 0; i < 10; i++)
{
var el = new BackgroundWorker();
el.DoWork += (s, e) =>
{
Thread.Sleep(5000);
};
workerList.Add(el);
checkedListBox1.Items.Add("el " + i);
}
}
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
var worker = workerList[e.Index];
if (worker.IsBusy)
{
e.NewValue = e.CurrentValue;
return;
}
if (e.NewValue == CheckState.Checked)
worker.RunWorkerAsync();
}
public List<BackgroundWorker> workerList { get; set; }
}
Think, that only funcion solution is set selection mode
CheckedListBox.SelectionMode = SelectionMode.None;
private void ItemCheck(object sender, ItemCheckEventArgs e)
{
if (busy)
e.NewValue = e.CurrentValue;
}
I got a windows form with around 140 numericUpDown elements and want all of them to do this:
private void numericUpDown_B1_RS_LS_Leave(object sender, EventArgs e)
{
if (numericUpDown_B1_RS_LS.Value < 1 || numericUpDown_B1_RS_LS.Value > 6)
{
numericUpDown_B1_RS_LS.BackColor = Color.Red;
}
else
{
numericUpDown_B1_RS_LS.BackColor = Color.White;
}
}
Is there a more comfortable way of doing this than just adding 140 functions to the form manually?
Assuming you want the same method for all NUDs on your form this will do it:
public Form1()
{
InitializeComponent();
foreach (Control ctl in this.Controls)
if (ctl.GetType() == typeof(NumericUpDown) ) ctl.Leave += numericUpDown_Leave;
}
private void numericUpDown_Leave(object sender, EventArgs e)
{
NumericUpDown NumericUD = (NumericUpDown) sender ;
if (NumericUD.Value < 1 || NumericUD.Value > 6)
{
NumericUD.BackColor = Color.Red;
}
else
{
NumericUD.BackColor = Color.White;
}
}
You can just as easily iterate over the Controls collection of another container, say a Panel or a GroupBox if the NUDs are not directly sitting on the Form. And if some NUDs should be excepted from that behaviour you could mark them in some way, maybe in their Tag or Name and check for that before adding their handlers ..
You should not write multiple functions for same code. Instead you can create just one function and assign it to the event method of your numericUpDown element i.e. "UpDown" event.
So whenever any of the element's "UpDown" event will fire, your same function will be executed. And as far as you want to write different methods for different elements, then consider that in your method
Method(object sender, EventArguments e)
sender is the actual sender object of your updownElement type, and that code will be executed for that particular object only.
You can take for loop to iterate your all 140 elements and assign this function to the "UpDown" element.
maybe you could write a static method to handle the adding of event handler recursively, something like:
private void frmMain_Load(object sender, EventArgs e)
{
AddHandleNumericUpdownLeave(this);
}
public static void AddHandleNumericUpdownLeave(Control theContrl)
{
if (theContrl.Controls != null && theContrl.Controls.Count > 0)
{
foreach (Control cControl in theContrl.Controls)
{
AddHandleNumericUpdownLeave(cControl);
}
}
else
{
NumericUpDown nudCtrl = theContrl as NumericUpDown;
if (nudCtrl != null)
{
nudCtrl.Leave += (object senderT, EventArgs eT) =>
{
var tmpCtrl = senderT as NumericUpDown;
if (tmpCtrl != null)
{
if (tmpCtrl.Value < 1 || tmpCtrl.Value > 6)
{
tmpCtrl.BackColor = Color.Red;
}
else
{
tmpCtrl.BackColor = Color.White;
}
}
}
}
}
}
but this might be costly if you have too many controls in a form...
I want to allow user to drag any item from MenuStrip to a ListBox.
I did it between to ListBoxes, but can not do it with MenuStrip.
Thanks a lot for your help.
I use WinForms, C#
For the destination ListBox I modified its property
this.listBox2.AllowDrop = true;
and created the following two events:
private void listBox2_DragOver(
object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect=DragDropEffects.All;
}
private void listBox2_DragDrop(
object sender, System.Windows.Forms.DragEventArgs e)
{
if(e.Data.GetDataPresent(DataFormats.StringFormat))
{
string str= (string)e.Data.GetData(
DataFormats.StringFormat);
listBox2.Items.Add(str);
}
}
What I need is what should be done to the source MenuStrip to allow drag items from it the ListBox, in over words how to make MenuStrip draggable.
Thanks to all for their help.
I found the solution:
The missing event is that I should add event to ToolStripMenuItem_MouseDown, I prefer to use right click instead of left click to avoid the conflict between ToolStripMenuItem_Click and the drag event, this the code:
AllowDrop = true;
private void tsmi_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
DoDragDrop(sender, System.Windows.Forms.DragDropEffects.Copy);
}
Add also this code to the ListView:
private void lvAllowDropListView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
System.Windows.Forms.ToolStripMenuItem button = e.Data.GetData(typeof(System.Windows.Forms.ToolStripMenuItem))
as System.Windows.Forms.ToolStripMenuItem;
if (button != null)
{
try
{
SmallImageList = sysIcons.SmallIconsImageList;
LargeImageList = sysIcons.LargeIconsImageList;
System.Windows.Forms.ToolStripMenuItem item = e.Data.GetData(typeof(System.Windows.Forms.ToolStripMenuItem))
as System.Windows.Forms.ToolStripMenuItem;
if (item != null)
{
AddToolStripMenuItem(item.Text, item.Name);
}
}
catch { }
}
}
private void AddToolStripMenuItem(string name, string tag)
{
System.Windows.Forms.ListViewItem item = new System.Windows.Forms.ListViewItem(name);
int Index = -1;
for (int i = 0; i < Items.Count;i++ )
if(Items[i].Tag.ToString() == tag)
{
Index = i;
break;
}
if (Index == -1)
{
item.Tag = tag;
Items.Add(item);
}
}
Drag Menu Strip Item is the same like ListBox item.
Check your code...