I have several NumericUpDowns looking like this:
public void numericUpDown1_ValueChanged (object sender, EventArgs e){}
Now if one of them reaches a certain Value they all get disabled. I do this, with the following code as follows
if(Value == 0)
{
numericUpDown1.Enabled = false;
numericUpDown2.Enabled = false;
numericUpDown3.Enabled = false;
.....
}
And so on.
My Question is: can I declare an array in my public form or something that includes all the NumericUpDowns I want disabled and then disable them calling the array?
If you are using .NET 3.5 or newer one you can access all controls of type by:
var my controls = Controls.OfType<NumericUpDown>();
And the iterate through:
foreach(var control in controls)
{
if(controls.Where(control => control.Value == 0).Any())
{
control.Enabled = false;
}
}
Related
I am creating A WPF application and am currently having issues with updating the visuals for a particular instance.
I have a ViewModel.Textlines which I am trying to change one element within that. It works and behaves fine from what I gather.
I am using Remove and Insert and it doesnt work. I use breakpoints and find out it all seems to work and the element has indeed been swapped out and when I check the OC it will show the values I wanted it to have and OnPropertyChanged Has been called after but it fails to update that. It might occure because the value is not a 'new' MFD_textline as I am just assigning it via =
Below is the code I am using
private void Controller_UpdateEvent(object sender, UpdateEventArgs e)
{
if(e.SystemName == "ALE47")
{
if(e.Values.ContainsKey("PageIndex") && e.Values.ContainsKey("Value") && e.Values.ContainsKey("TextLine"))
{
int pageIndex = (int)e.Values["PageIndex"].NewValue;
int value = (int)e.Values["Value"].NewValue;
textLine = new MFD_Textline();
textLine = (MFD_Textline)e.Values["TextLine"].NewValue;
ViewModel.TextLines.RemoveAt(value);
ViewModel.TextLines.Insert(value, textLine);
}
}
}
public void TextLineChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// when the textlines obserevable collection is changed (added to or removed) force a property changed to update the view
if (e.Action == NotifyCollectionChangedAction.Add)
{
if (TextLines.Count == 11)
{
OnPropertyChanged("textLines");
}
}
}
private ObservableCollection<MFD_Textline> textLines;
public ObservableCollection<MFD_Textline> TextLines
{
get { return textLines; }
set
{
textLines = value;
OnPropertyChanged("textlines");
}
}
Please let me know if there are any questions or if I have not quite explained it right.
This call is wrong OnPropertyChanged("textlines");
You should pass the Property's name, not the backing field's
OnPropertyChanged("TextLines");
I am trying to disable some menu strip items while a textbox is displaying "Calculating...". Once that value goes away, I wish to re-enable the menu items. Its purpose is not to interrupt MD5/CRC32 calculations. So far, I've tried various method of code, and have had no luck so far. What's listed below should work, but for some reason it does not. Any help would be appreciated.
// THIS PART WORKS
if (boxMD5.Text.Contains("Calculating") == true)
{
openROMToolStripMenuItem.Enabled = false;
saveROMDataToolStripMenuItem.Enabled = false;
asTXTToolStripMenuItem.Enabled = false;
asHTMLToolStripMenuItem.Enabled = false;
}
// THIS PART DOES NOT WORK
else if (boxMD5.Text.Contains("Calculating") == false)
{
openROMToolStripMenuItem.Enabled = true;
saveROMDataToolStripMenuItem.Enabled = true;
asTXTToolStripMenuItem.Enabled = true;
asHTMLToolStripMenuItem.Enabled = true;
}
I can't quite tell you why the code isn't doing what you expect, but I can make a suggestion that will change your approach and may help achieve your goal at the same time. What you are trying to do shouldn't be to disable the menu when the textbox contains "Calculating" but instead you should disable the menu while the calculations are being performed. From a user/UI perspective, these are the same thing, but the inner-workings of your program know better.
Based on you PasteBin code, try this:
private void openROMToolStripMenuItem_Click(object sender, EventArgs e)
{
//Other code omitted for brevity
if (File.Exists(OpenFileDialog1.FileName))
{
UpdateUI("Calculating...");
backgroundWorker1.RunWorkerAsync(OpenFileDialog1.FileName);
}
//Other code omitted for brevity
}
and
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
UpdateUI(e.Result.ToString());
}
where the new method UpdateUI() looks like this:
void UpdateUI(string hash)
{
var calculating = hash == "Calculating...";
if (!calculating)
{
progressBar1.Value = 0;
}
openROMToolStripMenuItem.Enabled = !calculating;
saveROMDataToolStripMenuItem.Enabled = !calculating;
asTXTToolStripMenuItem.Enabled = !calculating;
asHTMLToolStripMenuItem.Enabled = !calculating;
boxMD5.Text = hash;
}
Also, notice how you are able to just put !calculating in the if statement rather than calculating == false. This is because the value is already true or false so you don't have to compare it to anything to figure that out. The same thing applies to your original code but you don't need it anymore with this approach.
I have a form with 5 text boxes and a button, I want to check all these text boxes for empty or null user input.
Using this simple method:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (verifyUI() == true)
MessageBox.Show("user input for all textboxes was correct!");
else
MessageBox.Show("user input for all textboxes was missing!");
}
private bool verifyUI()
{
bool userInputOk = false;
foreach (Control cTxt in Controls.OfType<TextBox>())
{
if (string.IsNullOrWhiteSpace(cTxt.Text) || cTxt.Text == "")
{
userInputOk = false;
}
else
{
userInputOk = true;
}
}
return userInputOk;
}
}
When I enter a value in text box 1 , the method is checking only the first text box and returning true, and ignoring all other text boxes.
I am sure something is wrong in the logic of the method which I am using.
It seems you want to know if any input is wrong (or all the input is correct):
private bool verifyUI() {
return !Controls
.OfType<TextBox>()
.Any(cTxt => string.IsNullOrWhiteSpace(cTxt.Text));
}
or (equivalent All() implementation)
private bool verifyUI() {
return Controls
.OfType<TextBox>()
.All(cTxt => !string.IsNullOrWhiteSpace(cTxt.Text));
}
In your current code you constantly re-write userInputOk and so return the last value
The easiest way would be to use the All method:
private bool verifyUI()
{
return Controls.OfType<TextBox>().All(tb => !string.IsNullOrWhiteSpace(tb.Text));
}
You could also invert the logic and use the Any method as well. I prefer All in this case simply because it conveys the intention better and makes the logic more clear for the next person.
I think just for checking whether any textbox is not filled. following code is enough.
private bool verifyUI()
{
bool alluserInputsOk = true;
foreach (Control cTxt in Controls.OfType<TextBox>())
{
if (string.IsNullOrWhiteSpace(cTxt.Text))
{
userInputOk = false;
break;
}
}
return userInputOk;
}
or You can use .any() method with your list
Your code is actually only checking whether the last control in the list is blank or not, since that's where your iteration ends.
Your code checks only the last textbox it finds. Try this All() statement instead:
bool userInputOk = Controls.OfType<TextBox>()
.All(tb => !string.IsNullOrWhiteSpace(tb.Text));
Note that string.IsNullOrWhiteSpace() is true for string.Empty, too. So you don't need that extra check for string.Empty.
Actually, it's probably looping though all controls, but only returning the result of the last one, since you set the value of userInputOk back to true if the control has valid text. So the end result is the result for the last control. Now it's possible that textBox1 is the last control in the collection, depending on how they were added. You can either just remove the else block, which will flag userInputOk only if a control has an invalid value, or use Linq:
bool userInputOk =
!Controls.OfType<TextBox>()
.Any(cTxt => string.IsNullOrWhiteSpace(cTxt.Text))
See the linked screenshot below.
In short, I need those little white boxes to disappear - they're supposed to house an image, but there is no image, and so I'd rather they disappear.
I've accomplished this using the follow code:
foreach (ToolStripMenuItem menuItem in mnuMain.Items)
((ToolStripDropDownMenu)menuItem.DropDown).ShowImageMargin = false;
This works for what I guess are the main items, but not the sub-items, as you can see in the picture.
I've tried a few variations on the above code to try and get it to capture everything instead of just the first level items, but no luck.
What am I doing wrong?
http://i.imgur.com/bst1i4v.png
You should do that for sub items too. To do so, you can use this code:
private void Form1_Load(object sender, EventArgs e)
{
SetValuesOnSubItems(this.menuStrip1.Items.OfType<ToolStripMenuItem>().ToList());
}
private void SetValuesOnSubItems(List<ToolStripMenuItem> items)
{
items.ForEach(item =>
{
var dropdown = (ToolStripDropDownMenu)item.DropDown;
if (dropdown != null)
{
dropdown.ShowImageMargin = false;
SetValuesOnSubItems(item.DropDownItems.OfType<ToolStripMenuItem>().ToList());
}
});
}
This is a modified version of above. Use:
MainMenuStrip.HideImageMargins();
Because the recursive method performs the intended manipulation, I used overloading to make it clearer what is intended. Pattern matching is used because the above sample will throw an exception, not return null.
public static void HideImageMargins([NotNull] this MenuStrip menuStrip)
{
HideImageMargins(menuStrip.Items.OfType<ToolStripMenuItem>().ToList());
}
private static void HideImageMargins([NotNull] this List<ToolStripMenuItem> toolStripMenuItems)
{
toolStripMenuItems.ForEach(item =>
{
if (!(item.DropDown is ToolStripDropDownMenu dropdown))
{
return;
}
dropdown.ShowImageMargin = false;
HideImageMargins(item.DropDownItems.OfType<ToolStripMenuItem>().ToList());
});
}
I have a method that disables all the butttons on my window.
But i can't seem to get the type of Button to match it to the Resource collection
I'm using Expression Blend 3 with a c# code-behind
void DisableButtons()
{
for(int i = 0; i>= this.Resources.Count -1; i ++)
{
if (this.Resources[i].GetType() == typeof(Button))
{
Button btn = (Button)this.Resources[i];
btn.IsEnabled = false;
}
}
}
Update
Thanks for the answers!
Ok The loop is working but my code is incorrect.
this.Resources
Does not seem to include my buttons! This could be an Blend thing?
So Yeah.
I ended up doing it manually. Cause I'm hasty and there isn't a short easy solution. Thanks for all the input though!
void DisableButtons()
{
for(int i = 0; i < Resources.Count; i ++)
{
var btn = Resources[i] as Button;
if(btn != null)
{
btn.IsEnabled = false;
}
}
}
Easy way to implement it is use foreach instruction with LINQ query, but this way need more resuources whan easy for.
void DisableButtons()
{
foreach(var button in Resources.OfType<Button>())
{
button.IsEnabled = false;
}
}
It is possible I misunderstood something, but you're trying to find Buttons CONTAINED in your window in the RESOURCES of your window? Because those two things are different things alltogether.
If that is the case, either try setting this.IsEnabled = false (but that disables other things, not just buttons), or traverse the logical tree (or visual tree if silverlight) with LogicalTreeHelper/VisualTreeHelper, although that is a VERY expensive method.
Manual workaround would be to give names to all your buttons, make a list of them in codebehind and iterate that list.
However the best would be to create a boolean property called AreButtonsEnabled in your ViewModel (if you're not using MVVM than simply on the control itself - but make it DependencyProperty) and bind all your button's IsEnabled property to them! And then in codebehind simply set that boolean to false ... and magic ensues.
If this is not your case then sorry I wasted your time.
what about this?
if (this.Resources[i].GetType() == typeof(Button)))
or even better
if (this.Resources[i] is Button))
What about that?
if (this.Resources[i] is Button)
That way you can get anything that inherits from Button.
It looks like your loop statement is wrong. i>= this.Resources.Count -1 should be i <= this.Resources.Count - 1; It'll never get into your loop.
Also, this is just a style thing, but I'd rewrite it as:
for(int i = 0; i < Resources.Count; i ++)
{
Button btn = Resources[i] as Button; // btn will be null if not a Button
if( btn != null )
{
btn.IsEnabled = false;
}
}
I use a simple method.
First you create a bool.
bool enableButtons = true;
Now I add a timer to the form which is active all the time.
private void timer1_Tick(object sender, EventArgs e)
{
if (enableButtons = false)
{
button1.Enabled = false;
button2.Enabled = false;
}
else
{
button1.Enabled = true;
button2.Enabled = true;
}
}
So whenever I want to disable the buttons, I just change enableButtons to false.