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.
Related
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 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;
}
}
I've been asked to allow the user to (try to) change the selected value in the combobox event when its not valid. When he does so, I have to show an alert, and revert the SelectedItem of the combobox to its previous value.
I have something like:
private void cmbCountry_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Country selectedCountry = ((ComboBox)sender).SelectedItem as Country;
if (e.RemovedItems.Count > 0 && e.AddedItems.Count > 0 && !canChange)
{
e.Handled = true;
((ComboBox)sender).SelectedItem = e.RemovedItems[0];
return;
}
// Do stuff...
}
The problem is, although I set the e.Handled = true; The SelectionChanged event keeps firing giving me a StackOverflowException...
I guess its a common problem...
Do I have an elegant way of solving this?
After you checked that your overall logic is correct as suggested by #nvoigt you may use this as a brute force trick:
if (e.RemovedItems.Count > 0 && e.AddedItems.Count > 0 && canChange)
{
e.Handled = true;
canChange = false; // avoid infinite recursion
((ComboBox)sender).SelectedItem = e.RemovedItems[0];
canChange = true; // reset to original value
return;
}
This way the handler code is not called again from within the handler code.
If you change your SelectedItem in the ChangeHandler for the SelectedItem, you have an infinite recursion. The Handled flag only says this change was handled. For the new change you created, this function is called again.
The question is why is your change triggering your logic again? Shouldn't your change be the valid change? You will need to debug your program. Set a breakpoint and step through your method until you know what's wrong when you hit it a second time.
I have a checked list and when the program loads, I need to load a list of string and boolean to the checklist box. But whilst setting the booleans with
checkedListBoxControl1.SetItemChecked(i, checkedList[i]);;
the checkedListBoxControl1_ItemCheck-Event Fires. I dont want that because when it fires, it refreshes my database and takes a long time to complete. I only want it to fire if user changes the checked list Check state.
Note: I have
Presently I am using A flag to do that and its ugly and giving me a lot of problems else here
private void checkedListBoxControl1_ItemCheck(object sender, DevExpress.XtraEditors.Controls.ItemCheckEventArgs e) //fires second on check
{
int index = e.Index;
bool isChecked = e.State == CheckState.Checked;
this.mediaCenter.ItemManager.SetDirectoryCheck(index, isChecked);
if (this.IsUserClick)
BuildDatabaseAsync();
this.IsUserClick = false;
}
private bool IsUserClick;
private void checkedListBoxControl1_Click(object sender, EventArgs e) //Fires first on check
{
if (checkedListBoxControl1.SelectedItem == null) return;
IsUserClick = true;
}
May be my approach of filling the List-box Control is strange in the first place. But due to a lot of unwanted changes along the path. I do it as follows
private void BuildCheckListControl(string[] dirs)
{
IsUserClick = false;
this.checkedListBoxControl1.DataSource = dirs;
for (int i = 0; i < dirs.Length; i++)
checkedListBoxControl1.SetItemChecked(i, checkedList[i]);
}
checkedList[] contains an array of booleans corresponding to the dirs arrays
You can have a bool variable (class member not local variable) assigned false during your initialization. In the ItemCheck event check the bool variable and decide to proceed the DB check. Once the initialization completed set the bool variable to true.
If you don't want to create a boolean, that'll be checked you can (as stated in the comment) remove/add the eventhandler if you change your BuildCheckListControl-Method like this:
private void BuildCheckListControl(string[] dirs)
{
checkedListBoxControl1.ItemCheck -= checkedListBoxControl1_ItemCheck; //Will remove your Eventhandler
//IsUserClick = false; //You shouldn't need that anymore.
this.checkedListBoxControl1.DataSource = dirs;
for (int i = 0; i < dirs.Length; i++)
checkedListBoxControl1.SetItemChecked(i, checkedList[i]);
checkedListBoxControl1.ItemCheck += checkedListBoxControl1_ItemCheck; //Will add your Eventhandler again
}
I've created an array of RadioButtonList class, but apparently can't seem to access it or use the answer retrieved from it. I always get the exception: Object reference not set to an instance of an object
static int jimmy = 0;
protected void Button5_Click(object sender, EventArgs e)
{
int sizeOfPain = GlobalVariables.sympLCWR1Pain.Count;
RadioButtonList[] RBLPain = new RadioButtonList[sizeOfPain];
Label1.Visible = false;
RadioButtonList1.Visible = false;
Label[] Labella = new Label[sizeOfPain];
if (jimmy < sizeOfPain)
{
Labella[jimmy] = new Label();
RBLPain[jimmy] = new RadioButtonList();
Labella[jimmy].Text = GlobalVariables.sympLCWR1Pain[jimmy];
RBLPain[jimmy].Items.Add("Yes");
RBLPain[jimmy].Items.Add("No");
Panel1.Controls.Add(Labella[jimmy]);
Panel1.Controls.Add(RBLPain[jimmy]);
if (RBLPain[jimmy].SelectedIndex == 0)
{
GlobalVariables.sympLCWR1Yes.Add(GlobalVariables.sympLCWR1Pain[jimmy]);
}
}
else
{
Label2.Text = "YOUS DONE!";
Label3.Text = GlobalVariables.sympLCWR1Yes[0];
Button5.Visible = false;
}
jimmy++;
}
i get the exception at the if condition. Any help would be appreciated thanks :)
What that error means is that you are trying to access something that hasn't yet been instantiated. In your updated code, I see you have the following within your click event handler:
RadioButtonList[] RBLPain = new RadioButtonList[sizeOfPain];
Label[] Labella = new Label[sizeOfPain];
This means that every time the click event is handled, you are redeclaring the RBLPain and Labella arrays. Also, when execution leaves leaves the handler, the variables fall out of scope, so you will not be able to use them in other functions, or use the changes made within the handler from one call to the next. I don't know what the rest of your code is doing, but despite the seemingly unnecessary arrays, execution should survive your click event.
In your original post you were trying to access the SelectedItem.Text property of the RBLPain[jimmy]. In this revision you are checking the SelectedIndex instead. When SelectedIndex is -1, SelectedItem will be null, perhaps this led to your original problem. Regardless of what is changed on your form, because you are creating a new RadioButtonList during every click event, you are not working with the values from your form - SelectedIndex will always be -1 from what I can see.
I dont understand why you checking the condition .If you are creating rbl on buttonclick first item should always get selected. Anyway use RBLPain[jimmy].SelectedIndex=0;before if condition.