1

I just wondering is there any way to simplify this code:

MainWindow.xaml.cs

// Check checkbox
switch (num)
{
    case 0: checkbox0.IsChecked = true; break;
    case 1: checkbox1.IsChecked = true; break;
    case 2: checkbox2.IsChecked = true; break;
    case 3: checkbox3.IsChecked = true; break;
    case 4: checkbox4.IsChecked = true; break;
    case 5: checkbox5.IsChecked = true; break;
    default: break;
}

MainWindow.xaml

<CheckBox x:Name="checkbox0">assets/appfilter.xml</CheckBox>
<CheckBox x:Name="checkbox1">xml/appfilter.xml</CheckBox>
<CheckBox x:Name="checkbox2">xml/appmap.xml</CheckBox>
<CheckBox x:Name="checkbox3">xml/theme__resources.xml</CheckBox>
<CheckBox x:Name="checkbox4">xml/drawable.xml</CheckBox>
<CheckBox x:Name="checkbox5">values/icon__pack.xml</CheckBox>
Hadif Hatta
  • 75
  • 1
  • 11
  • 1
    You can add your checkboxes to an array, and then you can reference the required checkbox by its index in the array. But this only really makes sense, if you need to refer to the checkboxes by index more than once, since you have to have code adding each one individually to the array. – Jonathan Willcock May 26 '21 at 04:59
  • 2
    As a general rule, if you want to map an index to some specific object, an array or dictionary would be an appropriate data structure. See duplicates. That said, in WPF it's rare that you should be referencing _any_ control directly in code-behind, never mind a large number of them. More likely this is an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) question and what you really should be asking is how to properly use data binding so that your checkboxes work the right way without having an explicit variable reference to them at all. – Peter Duniho May 26 '21 at 06:12
  • 1
    Consider using an ItemsControl which has its ItemsSource property bound to a collection of data items. The CheckBox would be declared in the ItemTemplate of the ItemsControl, and would have its Content and IsChecked property bound to a string and a bool property of the data item class. See [Data Templating Overview](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/data-templating-overview?view=netframeworkdesktop-4.8). – Clemens May 26 '21 at 06:31

2 Answers2

2

You could use an array with an index. But that will mean you must guarantee the order and that "num" corresponds to the correct index. An alternative is a dictionary.

//Define your dictionary
Dictionary<int, CheckBox> checkBoxDict = new Dictionary<int, CheckBox>(6);
checkBoxDict.Add(checkbox0);  //Repeat for all Checkboxes


//Then in your code
if (checkBoxDict.TryGetValue(num, var out checkBox))
    checkBox.IsChecked = true;

But actually I would question if this is a better approach. Using a switch statement the code is easy to understand and easy to expand. A dictionary is good if you need to do similar things in different places but would use up more memory (ok, not exactly a lot for so few items!), and if you want to expand you must remember to add the checkbox to the dictionary.

jason.kaisersmith
  • 8,712
  • 3
  • 29
  • 51
  • I do not understand how the use of a dictionary obviates the need for the order to be correct. You still have to add the checkboxes to the dictionary with the correct key. How is this any different to adding to an array with the correct index? An array has the advantage that it can be initialised with all the elements, making the code simpler. – Jonathan Willcock May 26 '21 at 05:23
  • 1
    @JonathanWillcock: If you use an array then the order of insertion is important, and if you use a collection then the order is not always guaranteed. With a dictionary, you use the "Num" as a key and not an indexer. So you don't need to worry about order anymore. Yes of course you still need to add the correct key, but you need to identify the item somehow so you will always need this. You can also use something else as a key such as the checkbox name. – jason.kaisersmith May 26 '21 at 06:00
  • With the greatest of respect, the order of insertion is only important if you auto-initialise (admittedly one of the nicest benefits of using an array). If you insert your elements into a pre-sized array, you can do so in any order, all that matters is that the index matches the correct number; but this is exactly the same requirement as the key in a dictionary. IMHO, in the OP's case, there is no practical difference between an array and a dictionary, except for the fact that an array uses less overhead and is easier to initialise. – Jonathan Willcock May 26 '21 at 06:11
  • @JonathanWillcock Well that's the good thing about programming, there are many ways to solve the same problem. This is how I would solve it, but in the end they all have pros and cons and it is about selecting which you prefer. – jason.kaisersmith May 26 '21 at 06:42
2

You can get a reference to the control using FindName

var checkbox = this.FindName($"checkbox{num}") as CheckBox;
checbox.IsChecked = true;
John Wu
  • 50,556
  • 8
  • 44
  • 80
  • 1
    Should use a straight cast `(Checkbox)`, or use `as` with the next line `checkbox?.IsChecked = true`. Right now the code effectively reads "null is possible, but we're not going to bother testing for it". – Zer0 May 26 '21 at 06:06
  • This seems way easier than other methods, thanks! – Hadif Hatta May 28 '21 at 10:36