我试图用Canvas
填充Ellipse
(Rectangle
和public MainWindow()
{
InitializeComponent();
this.Loaded += delegate { InitializeSourceCanvas(); };
}
private void InitializeSourceCanvas()
{
var rnd = new Random();
const int height = 30, width = 30;
for (int i = 0; i < 25; i++)
{
var shape = rnd.Next(10) > 4 ? (Shape)new Ellipse() : (Shape)new Rectangle();
shape.Width = height;
shape.Height = width;
shape.Stroke = new SolidColorBrush(Colors.Black);
shape.StrokeThickness = 1;
shape.Fill = PickRandomBrush();
Canvas.SetLeft(shape, rnd.NextDouble() * (_source.ActualWidth - width));
Canvas.SetTop(shape, rnd.NextDouble() * (_source.ActualHeight - height));
_source.Children.Add(shape);
}
}
private Brush PickRandomBrush()
{
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;
}
)。我需要选择一种随机颜色来填充形状。对于所有形状,我总是具有相同的随机颜色的问题。
当我调试我的代码时,我得到随机颜色。以下是我的代码:
{{1}}
答案 0 :(得分:3)
像Nuke建议的那样,new
你的Random对象在for循环之外,所以它只被实例化一次,然后每次传递相同的一个。
Random rnd = new Random();
for (int i = 0; i < 25; i++)
{
...
shape.Fill = PickRandomBrush(rnd);
...
}
然后编辑PickRandomBrush方法,看起来像,
private Brush PickRandomBrush(Random rnd)
{
Brush result = Brushes.Transparent;
Type brushesType = typeof(Brushes);
PropertyInfo[] properties = brushesType.GetProperties();
int random = rnd.Next(properties.Length);
result = (Brush)properties[random].GetValue(null, null);
return result;
}
编辑: k,sraboy在快速连续运行这个代码时提出了一个很好的观点 - 如果调用得足够快,这将有相同的种子。这是一个不优雅的解决方案,但合理保证是独一无二的:
Random rnd = new Random(Guid.NewGuid().ToString().GetHashCode());
(这会取代第一行)
答案 1 :(得分:2)
来自MSDN:
[..]通过调用默认构造函数紧密连续创建的不同随机对象将具有相同的默认种子值,因此将生成相同的随机数集。使用单个Random对象生成所有随机数可以避免此问题。
答案 2 :(得分:0)
Random是因为你没有将函数绑定到一个计时器,这意味着它每次创建时都具有相同的条件。
一种解决方案是将随机数绑定到Systemtime.Now 另一种解决方案是使用相同的Random而不是创建一个新的。