0

I am writing a code in C# for developing a Windows Phone 8 App.

I have 8 Buttons named ( f1 ,f2 ,f3 ...... f8)

Now, I want to add their Text value into an array. I know how to do this but it will take 8 lines of code.

Example:

Numbers[0] = Convert.ToInt32(f1.Content);
Numbers[1] = Convert.ToInt32(f2.Content);
.
.
.
Numbers[7] = Convert.ToInt32(f8.Content);

Is there a way to write a loop to make all this process for me? Something like this:

for(int i=0; i < 8 ; i++)
    Numbers[i] = Convert.ToInt32(fX.Content);

where X starts with the Value 1 (f1) and then 2 and so on. Is there any way I can do that in C#?

Katie Kilian
  • 6,815
  • 5
  • 41
  • 64
GabourX
  • 283
  • 2
  • 5
  • 14
  • 1
    Welcome to Stack Overflow! I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not". http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles – Katie Kilian Mar 14 '14 at 20:48
  • possible duplicate of [Set multiple buttons.Content in a for (each) loop](http://stackoverflow.com/questions/15420157/set-multiple-buttons-content-in-a-for-each-loop) – O. R. Mapper Mar 14 '14 at 20:53

2 Answers2

2

Assuming you have a grid control with the name MainGrid (it doesn't have to be a grid control, anything will work. Just adjust your code accordingly)

int[] numbers = MainGrid.Children.OfType<Button>()
            .Select(x => Convert.ToInt32(x.Content)).ToArray();

Here's some example XAML that goes with the above code

<Grid x:Name="MainGrid">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Grid.Column="0" Content="1" x:Name="F1" />
    <Button Grid.Row="1" Grid.Column="0" Content="2" x:Name="F2" />
    <Button Grid.Row="2" Grid.Column="0" Content="3" x:Name="F3" />
    <Button Grid.Row="3" Grid.Column="0" Content="Do not count me" />
</Grid>

As LordTakkera pointed out in the comments, this code would fail if you had other buttons in the same parent container that you didn't want to get the value of. In such a case, you'd need an additional Where() clause, which would look like this:

int[] numbers = MainGrid.Children.OfType<Button>()
            .Where(x => x.Name.Contains("F"))
            .Select(x => Convert.ToInt32(x.Content))
            .ToArray();

Since LINQ can be confusing and unclear if you're not familiar with it, here's a more traditional way of doing the same thing:

//Unless you have a specific reason for wanting an int array, a list is easier to work with
List<int> numbers = new List<int>();

//Use .OfType<>() So that you don't have to cast each control to a button in the loop
foreach(Button button in MainGrid.Children.OfType<Button>())
{
    //If it's not one of our named buttons, continue the loop
    if(! button.Name.StartsWith("F")) continue;

    int buttonValue = Convert.ToInt32(button.Content);
    numbers.Add(buttonValue);
}
Jedediah
  • 1,916
  • 16
  • 32
  • Note that this only works if these are the ONLY buttons on the grid. You would need a "where" clause on the name if there are others. – BradleyDotNET Mar 14 '14 at 21:09
  • That's true. Good call – Jedediah Mar 14 '14 at 21:09
  • @Jedediah what is X ? – GabourX Mar 14 '14 at 21:14
  • In this case `x` is a local anonymous variable. In basic terms, it's the "current" button. To make it clearer, this could be written like this: `.Select(button => Convert.ToInt32(button.Content))` `x` is just typical short-hand when using LINQ – Jedediah Mar 14 '14 at 21:16
  • +1, this is a good answer, though LINQ seems a bit overkill perhaps :) – BradleyDotNET Mar 14 '14 at 21:29
  • @Jedediah what .ToArray() does ? – GabourX Mar 14 '14 at 21:45
  • `.ToArray()` Converts the returned `IEnumerable` that `.Select()` returns into an integer array. You could also call `.ToList()` if you wanted a `List` instead of an array. That probably made it less clear, if you're not familiar with LINQ and generics... – Jedediah Mar 14 '14 at 22:58
0

I am assuming you are in your code-behind, since you "could" use the control names.

To do this, use the FindName function (MSDN):

for(int i=0; i < 8 ; i++)
    Numbers[i] = Convert.ToInt32(((Button)FindName("f" + i)).Content);

This isn't a very XAML/WPF/MVVM way of doing this, so you might want to look at setting up an items control bound to a list of the numbers (that you could then call sum on), but this should work for the posted scenario.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117