0

This is just basic example:

if (a == b)
{
    textBox1.Text = "a == b"; 
    textBox1.IsEnabled = true; 
    textBox2.Text = "EXAMPLE2"; 
    textBox2.IsEnabled = false; 
    textBox3.Text = "EXAMPLE3"; 
    textBox3.IsEnabled = false; 
    textBox4.Text = "EXAMPLE4"; 
    textBox4.IsEnabled = false; 
    textBox5.Text = "EXAMPLE5"; 
    textBox5.IsEnabled = false; 
}
else 
{
    textBox1.Text = "a != b"; 
    textBox1.IsEnabled = false; 
    textBox2.Text = "EXAMPLE2"; 
    textBox2.IsEnabled = true; 
    textBox3.Text = "EXAMPLE3"; 
    textBox3.IsEnabled = true; 
    textBox4.Text = "EXAMPLE4"; 
    textBox4.IsEnabled = true; 
    textBox5.Text = "EXAMPLE5"; 
    textBox5.IsEnabled = true;
}  

This seems pretty tedious. I was wondering if there's a better way to handle situations like that? I just have this feeling that all the Pros out there don't do things using this 1x1x1x.... method.

Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169
PiZzL3
  • 2,092
  • 4
  • 22
  • 30
  • Moving `textBoxN.Text = "EXAMPLEN";` out of the `if` would help. – H H Mar 27 '11 at 18:33
  • The code above has no functional purpose. It's only there to illustrate a ton of form settings being changed. – PiZzL3 Mar 27 '11 at 18:54

2 Answers2

6

There are lots of ways to refactor this sort of code to give something more succinct. It really does become a matter of experience and preference to choose the method that is appropriate for each case.

To that end, I've listed below several options that I find serve me well:

Binding

Binding particularly within WPF gives a very powerful way of easily updating form objects. In your Xaml you apply a datacontext (generally for the form/window) and bound property for each object which then allows you to then update properties in your c# code and have them automatically reflected in the form objects.

One big advantage of this is getting all that tedious object.Text = "xyz" code out of the way.

In your given example, you could introduce a boolean property TextBoxesEnabled which is bound to the enabled property of your text boxes, and reflects whether a == b.

Domain objects

This follows on from the binding approach—in your example above it looks like all your properties are dependant of only two external pieces of data ("a" and "b"). In this situation your are often limited to doing something just like you have, where you need to set your UI properties within lots of procedural code.

However, more often you can introduce expressive domain objects that have properties that map directly to UI properties. For example, perhaps you have a User object, with a Name property, and then a user window, with a name textbox.

Now your domain object will be provided by calls into your service layer and data access infrastructure, and due to binding automatically displayed in your UI.

Code refactoring

Even where you are needing to set lots of properties directly without the ability to use more expressive objects and binding, there will often be some simple refactorings that can help.

In the code example you gave, two easy refactorings leap out to me:

  1. a == b is a Boolean evaluation so you could have something like:

    bool enableTextBoxes = a == b;
    
    TextBox1.Enabled = enableTextBoxes;
    TextBox2.Enabled = enableTextBoxes;
    // etc...
    
  2. You are setting the text to the same thing in the branches of the if, so take that out of the if and just have it once (though I'm guessing this is just because you were giving trivial example code).

  3. You can loop over collections of controls, so if you need to set large numbers of control values to the same thing you can just do iterate over them and assign to each.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
David Hall
  • 32,624
  • 10
  • 90
  • 127
1

Assuming:
1. your controls have a pattern myControl1, myControl2, etc. (e.g textBox1, textBox2, etc)
2. your controls are all children of same FrameworkElement parent (e.g. all of them are within a Grid)

you can try something like:

bool shouldEnable = (a == b); //or whatever logic you want to have to decide the enable/disable value

for(i=0; i<10; i++)
{
    string myControlName = "textBox" + i.ToString(); //assuming your pattern to be textBox1, textBox2, etc.
    object myControl = myGrid.FindName(myControlName); //assuming your textboxes present in a Grid named "myGrid"
    if(myControl is TextBox) //assuming your controls to be TextBoxes
    {
        TextBox myTextBox = (TextBox)myControl;
        myTextBox.IsEnabled = shouldEnable;
        myTextBox.Text = "whatever you want based on your logic";
    }
}

Do remember:
1. to refer to FindName on MSDN: FrameworkElement.FindName
2. in case all of your controls are not under one parent, you might want to have a look at: How can I find WPF controls by name or type?
3. to be aware of performance implications (you may want to check it).


Also see: Find Controls by Name in WPF

Community
  • 1
  • 1
publicgk
  • 3,170
  • 1
  • 26
  • 45
  • Hmmm... your code is very very interesting... I didn't know I could get Form controls by a string name. That opens up a great great great deal of new possibilities.. Thank you! – PiZzL3 Mar 27 '11 at 21:27