I'm trying to use StreamGeometry in WPF to create a bunch of random shapes on the fly. I read that this was supposed to give the best performance. Unfortunately, I can't figure out how to change the color on each shape independtly. For example, int the code below:
private void CreateGraphics(){
int NUM_SHAPES = 100;
int RECT_MAX_WIDTH = 100;
int RECT_MAX_HEIGHT = 100;
StackPanel mainPanel = new StackPanel();
StreamGeometry geometry = new StreamGeometry();
geometry.FillRule = FillRule.EvenOdd;
using (StreamGeometryContext context = geometry.Open())
{
for (int i = 0; i < NUM_SHAPES; i++)
{
Path myPath = new Path();
double width = RECT_MAX_WIDTH * RAND.NextDouble();
double height = RECT_MAX_HEIGHT * RAND.NextDouble();
int x = (int)(SCREEN_WIDTH * RAND.NextDouble());
int y = (int)(SCREEN_HEIGHT * RAND.NextDouble());
int fill_color_num = RAND.Next(1, MAX_COLORS);
Color fill_color = Color.FromArgb(0xFF,
(byte)(fill_color_num & 0xFF),
(byte)((fill_color_num >> 8) & 0xFF),
(byte)((fill_color_num >> 16) & 0xFF));
int edge_color_num = RAND.Next(1, MAX_COLORS);
Color edge_color = Color.FromArgb(0xFF,
(byte)(edge_color_num & 0xFF),
(byte)((edge_color_num >> 8) & 0xFF),
(byte)((edge_color_num >> 16) & 0xFF));
myPath.StrokeThickness = 2;
myPath.Stroke = new SolidColorBrush(edge_color);
myPath.Fill = new SolidColorBrush(fill_color);
int left_edge = x - (int)(width / 2);
int right_edge = x + (int)(width / 2);
int top_edge = y - (int)(height / 2);
int bottom_edge = y + (int)(height / 2);
if (left_edge < 0) { left_edge = 0; }
if (right_edge > SCREEN_WIDTH) { right_edge = SCREEN_WIDTH; }
if (top_edge < 0) { top_edge = 0; }
if (bottom_edge > SCREEN_HEIGHT) { bottom_edge = SCREEN_HEIGHT; }
context.BeginFigure(new Point(left_edge, bottom_edge), true , true );
context.LineTo(new Point(left_edge, top_edge), true , true );
context.LineTo(new Point(right_edge, top_edge), true , true );
context.LineTo(new Point(right_edge, bottom_edge), true , true );
geometry.Freeze();
myPath.Data = geometry;
mainPanel.Children.Add(myPath);
}
}
this.Content = mainPanel;
}
I was expecting that by setting the Path.Fill and Path.Stroke properties, that I would get different colors for each rectangle. It seems that I only get the last defined color applied to all the rectangles. Does anyone know how to set unique colors for each rectangle?
EDIT: I tried placing the StreamGeometry object declaration inside the for loop, as one user suggested. For some reason I only get 2 shapes. Here is the code:
private void CreateGraphics()
{
int NUM_SHAPES = 3;
int RECT_MAX_WIDTH = 100;
int RECT_MAX_HEIGHT = 100;
StackPanel mainPanel = new StackPanel();
for (int i = 0; i < NUM_SHAPES; i++)
{
StreamGeometry geometry = new StreamGeometry();
geometry.FillRule = FillRule.EvenOdd;
using (StreamGeometryContext context = geometry.Open())
{
Path myPath = new Path();
double width = RECT_MAX_WIDTH * RAND.NextDouble();
double height = RECT_MAX_HEIGHT * RAND.NextDouble();
int x = (int)(SCREEN_WIDTH * RAND.NextDouble());
int y = (int)(SCREEN_HEIGHT * RAND.NextDouble());
int fill_color_num = RAND.Next(1, MAX_COLORS);
Color fill_color = Color.FromArgb(0xFF,
(byte)(fill_color_num & 0xFF),
(byte)((fill_color_num >> 8) & 0xFF),
(byte)((fill_color_num >> 16) & 0xFF));
int edge_color_num = RAND.Next(1, MAX_COLORS);
Color edge_color = Color.FromArgb(0xFF,
(byte)(edge_color_num & 0xFF),
(byte)((edge_color_num >> 8) & 0xFF),
(byte)((edge_color_num >> 16) & 0xFF));
myPath.StrokeThickness = 2;
myPath.Stroke = new SolidColorBrush(edge_color);
myPath.Fill = new SolidColorBrush(fill_color);
int left_edge = x - (int)(width / 2);
int right_edge = x + (int)(width / 2);
int top_edge = y - (int)(height / 2);
int bottom_edge = y + (int)(height / 2);
if (left_edge < 0) { left_edge = 0; }
if (right_edge > SCREEN_WIDTH) { right_edge = SCREEN_WIDTH; }
if (top_edge < 0) { top_edge = 0; }
if (bottom_edge > SCREEN_HEIGHT) { bottom_edge = SCREEN_HEIGHT; }
context.BeginFigure(new Point(left_edge, bottom_edge), true , true );
context.LineTo(new Point(left_edge, top_edge), true , true );
context.LineTo(new Point(right_edge, top_edge), true , true );
context.LineTo(new Point(right_edge, bottom_edge), true , true );
geometry.Freeze();
myPath.Data = geometry;
mainPanel.Children.Add(myPath);
}
}
this.Content = mainPanel;
}