28

I'm looking for a method to pick a random Brush in Brushes collection (Aqua,Azure, ...Black,...). Any clue?

ojsim
  • 457
  • 2
  • 6
  • 7

7 Answers7

50

You can use a bit of reflection, like so:

private Brush PickBrush()
{
    Brush result = Brushes.Transparent;

    Random rnd = new Random();

    Type brushesType = typeof(Brushes);

    PropertyInfo[] properties = brushesType.GetProperties();

    int random = rnd.Next(properties.Length);
    result = (Brush)properties[random].GetValue(null, null);

    return result;
}

That will do the trick. You may want to change the randomisation to use an external Random instance, instead of re-creating a new seed each time the method is called, as in my example.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Edwin Groenendaal
  • 2,304
  • 16
  • 8
14

If you simply want random colors, any random colors, just use a Random object to generate (a)rgb values between 0 and 255.

If you actually want a named color (Brush) you could store all of the predefined values in a lookup table and randomly generate an index into it. As Brushes is a class (as opposed to an `enum') it gets a bit trickier to randomly fetch a static property, but you could use reflection to do it. Store all of the property names via reflection in a lookup table and then use reflection once again to get the value of the property that corresponds to the stored name.

private List<Brush> _brushes;
private void InitBrushes()
{
    _brushes = new List<Brush>();
    var props = typeof(Brushes).GetProperties( BindingFlags.Public | BindingFlags.Static );
    foreach( var propInfo in props )
    {
        _brushes.Add( (Brush)propInfo.GetValue( null, null ) );
    }
}

And to get a random Brush...

private Random _rand = new Random();
private Brush GetRandomBrush()
{
   return _brushes[_rand.Next(_brushes.Count)];
}

I hope I didn't make any errors here, I'm on my phone and can't test it out, but you get the general idea.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • To expand quickly on the first sentence & save future new-to-wpf-me's some googling, `Color myColor = Color.FromRgb(randomByte1, randomByte2, randomByte3); SolidColorBrush myBrush = new SolidColorBrush(myColor);` (though admittedly the second suggestion in this answer is *much* neater) Thanks! – ruffin Mar 09 '15 at 13:58
7

The Brushes is not a collection, it's a class with a lot of static properties. You could pick out the static properties with reflection, but I would suggest that you just create an array with the brushes that you want:

Brush[] brushes = new Brush[] {
  Brushes.AliceBlue,
  Brushes.AntiqueWhite,
  Brushes.Aqua,
  ...
  Brushes.YellowGreen
};

Then you can easily pick one by random:

Random rnd = new Random();
Brush brush = brushes[rnd.Next(brushes.Length)];
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 2
    I don't think the one time cost of using reflection would justify this approach. You also get the benefit of grabbing all properties if the class is ever modified in a future version of the framework. Is there another reason you suggest doing it this way? – Ed S. May 21 '11 at 21:58
  • @Ed S.: A lot of people seem to be using reflection as the first resort, so I suggested an alternative to show that you don't have to use reflection for everything. – Guffa May 21 '11 at 22:47
  • 1
    Yeah, that's why I mentioned doing it this way as as well. That said, this is a case in which reflection seems to be the best route. – Ed S. May 22 '11 at 01:09
  • Why the downvote? If you don't explain what it is that you think is wrong, it can't improve the answer. – Guffa Dec 18 '14 at 14:24
3
Random rand = new Random();
Brush brush = new SolidColorBrush(Color.FromRgb((byte) rand.Next(0, 256), (byte) rand.Next(0, 256), (byte) rand.Next(0, 256)));
Kyriacos
  • 83
  • 1
  • 2
  • 5
1

I have added a utility method as bellow, which will return a random color.

    public static Brush getRandomBrush()
    {
        string[] brushArray = typeof(Brushes).GetProperties().
                                    Select(c => c.Name).ToArray();

        Random randomGen = new Random();
        string randomColorName = brushArray[randomGen.Next(brushArray.Length)];
        SolidColorBrush color = (SolidColorBrush)new BrushConverter().ConvertFromString(randomColorName);

        return color;
    }
Malu MN
  • 141
  • 2
  • 10
0

This should work:

Brush RandomBrush()
{
    PropertyInfo[] brushInfo = typeof(Brushes).GetProperties();
    Brush[] brushList = new Brush[brushInfo.Length];
    for(int i = 0;i < brushInfo.Length;i++)
    {
        brushList[i] = (Brush)brushInfo[i].GetValue(null, null);
    }
    Random randomNumber = new Random(DateTime.Now.Second);
    return brushList[randomNumber.Next(1, brushList.Length)];
}
moaz786
  • 40
  • 5
0

To get WPF default brushes:

var brushes = typeof(Brushes).GetProperties(BindingFlags.Public | BindingFlags.Static).Select(pi => (Brush)pi.GetValue(null, null));
chainerlt
  • 215
  • 3
  • 8