Reputation: 25
I can't think of a way to currently assign the content and matching colour of a button randomly and I would be very thankful if someone could help me.
Currently the code to assign my button content and colour is
public void SetButtonContent(TextBlock reagentText, TextBlock transMetalText,
Button opt1, Button opt2, Button opt3, Button opt4, Button opt5, Button opt6, Button opt7, Button opt8)
{
string pickedMetal = CycleThroughMetals(); //randomly picks a metal
string pickedReagent = CycleThroughReagents(); //randomly picks reagent
reagentText.Text = pickedReagent;
transMetalText.Text = pickedMetal;
BrushConverter bc = new BrushConverter();
switch (pickedMetal)
{
case "Copper":
opt1.Content = string.Format("{0} \n {1} \n{2}",Cu.hexAqColour, Cu.hexAqFormula, Cu.hexAqState);
opt1.Background = Brushes.Blue;
opt2.Content = string.Format("{0} \n {1} \n{2}",Cu.dilNaOHRctColour, Cu.dilNaOHRctFormula, Cu.dilNaOHRctState);
opt2.Background = Brushes.Blue;
opt3.Content = string.Format("{0} \n {1}",Cu.excessNaOHColour, Cu.excessNaOHFormula, Cu.excessNahOHState);
opt3.Background = Brushes.Blue;
opt4.Content = string.Format("{0} \n {1} \n{2}", Cu.dilNH3RctColour, Cu.dilNH3RctFormula, Cu.dilNH3RctState);
opt4.Background = Brushes.Blue;
opt5.Content = string.Format("{0} \n {1} \n{2}",Cu.ExcessNH3Colour, Cu.ExcessNH3Formula, Cu.ExcessNH3State);
opt5.Background = Brushes.DarkBlue;
opt6.Content = string.Format("{0} \n {1} \n{2}",Cu.saltRctColour, Cu.saltRctFormula, Cu.saltRctState);
opt7.Content = string.Format("{0} \n {1} \n{2}",Cu.Na2CO3RctColour, Cu.Na2CO3RctFormula, Cu.Na2CO3RctState);
opt7.Background = Brushes.Blue;
opt8.Content = string.Format("{0} \n {1} \n{2}",Cu.ClRctColour, Cu.ClRctFormula, Cu.ClRctState);
opt8.Background = Brushes.Yellow;
break;
default:
break;
}
I've only included one case with in my switch statement just to make it easier to read but in my code there is 6 cases but all perform pretty much the same function.
But I'd like to assign the button content randomly rather than manually but I'm unsure how to do this.
I'd also greatly appreciate any constructive criticism as I am quite a beginner in regards to WPF and C#.
Upvotes: 1
Views: 165
Reputation: 514
A simple solution would be storing your buttons, contents and colors inside lists, randomizing them and then assigning their values like this:
public void SetButtonContent(TextBlock reagentText, TextBlock transMetalText,
Button opt1, Button opt2, Button opt3, Button opt4, Button opt5, Button opt6, Button opt7, Button opt8)
{
string pickedMetal = CycleThroughMetals(); //randomly picks a metal
string pickedReagent = CycleThroughReagents(); //randomly picks reagent
List<Button> buttons = new List<Button>{opt1, opt2, opt3, opt4, opt5, opt6, opt7, opt8};
List<Tuple<string, Brush>> contentsAndColors;
reagentText.Text = pickedReagent;
transMetalText.Text = pickedMetal;
BrushConverter bc = new BrushConverter();
switch (pickedMetal)
{
case "Copper":
contentsAndColors = new List<Tuple<string, Brush>>{
new Tuple<string, Brush>(string.Format("{0} \n {1} \n{2}",Cu.hexAqColour, Cu.hexAqFormula, Cu.hexAqState), Brushes.Blue),
new Tuple<string, Brush>(string.Format("{0} \n {1} \n{2}",Cu.dilNaOHRctColour, Cu.dilNaOHRctFormula, Cu.dilNaOHRctState), Brushes.Blue ),
new Tuple<string, Brush>(string.Format("{0} \n {1}",Cu.excessNaOHColour, Cu.excessNaOHFormula, Cu.excessNahOHState),Brushes.Blue ),
new Tuple<string, Brush>(string.Format("{0} \n {1} \n{2}", Cu.dilNH3RctColour, Cu.dilNH3RctFormula, Cu.dilNH3RctState),Brushes.Blue ),
new Tuple<string, Brush>(string.Format("{0} \n {1} \n{2}",Cu.ExcessNH3Colour, Cu.ExcessNH3Formula, Cu.ExcessNH3State),Brushes.DarkBlue ),
new Tuple<string, Brush>(string.Format("{0} \n {1} \n{2}",Cu.saltRctColour, Cu.saltRctFormula, Cu.saltRctState),Brushes.Blue ),
new Tuple<string, Brush>(string.Format("{0} \n {1} \n{2}",Cu.Na2CO3RctColour, Cu.Na2CO3RctFormula, Cu.Na2CO3RctState),Brushes.Yellow ),
new Tuple<string, Brush>(string.Format("{0} \n {1} \n{2}",Cu.ClRctColour, Cu.ClRctFormula, Cu.ClRctState),Brushes.Blue );
};
break;
default:
break;
}
//ensure buttons, contents and colors are of the same size
System.Diagnostics.Debug.Assert(buttons.Count != contents.Count || buttons.Count != colors.Count, "Lists are not same in size");
//randomize the order
Random rng = new Random();
buttons.OrderBy(x => rng.Next());
contentsAndColors.OrderBy(x => rng.Next());
//assign content and color to buttons
for(int iButton = 0; iButton < buttons.Count; ++iButton)
{
buttons[iButton].Content = contentsAndColors[iButton].Item1;
buttons[iButton].Background = contentsAndColors[iButton].Item2;
}
}
As for the general tips/criticism:
The OrderBy(x => rng.Next());
statement combines linq and lambda mechanics which are very useful in manipulating lists, and lambda mechanics are generally useful in a multitude of ways, i'd suggest reading up on them.
About OrderBy(x => rng.Next());
: Did you creating an Enum for your metals instead of using strings? this way you will be safe against typos and such, as the compiler will check those for you. you can simply create an enum this way:
public enum Metals
{
Copper,
Iron,
Gold
}
And later you can use its values this way:
switch (pickedMetal)
{
case Metals.Copper:
You could also consider using a parameter list in your method declaration if the numbers of buttons will change over developement time:
public void SetButtonContent(TextBlock reagentText, TextBlock transMetalText, params Button[] opts)
{
Button opt1 = opts[0];
}
params
is a keyword which allows you to write multiple objects in the call of a function which will then be combined into an array. As such your previous calls of SetButtonContent
won't be harmed.
Upvotes: 3