How to draw a rectangle in WPF at a specific x,y screen location?

zetar picture zetar · Oct 6, 2012 · Viewed 39.7k times · Source

In C#, WPF I've created a rectangle:

        Rectangle myRgbRectangle = new Rectangle();
        myRgbRectangle.Width = 1;
        myRgbRectangle.Height = 1;
        SolidColorBrush mySolidColorBrush = new SolidColorBrush();

Yes, I really just want it to be 1 pixel by 1 pixel. And I want to change the color based on the variable height like so:

        mySolidColorBrush.Color = Color.FromArgb(255, 0, 0, (byte)height);
        myRgbRectangle.Fill = mySolidColorBrush;

Now, how do I draw at a specific x,y location on the screen? I do have a grid (myGrid) on my MainWindow.xaml.

Thanks!


Here's the pertinent code:

        myRgbRectangle.Width = 1;
        myRgbRectangle.Height = 1;
        SolidColorBrush mySolidColorBrush = new SolidColorBrush();

        int height;
        for (int i = 0; i < ElevationManager.Instance.heightData.GetLength(0); i++)
            for (int j = 0; j < ElevationManager.Instance.heightData.GetLength(1); j++)
            {
                height = ElevationManager.Instance.heightData[i, j] / 100;
                // Describes the brush's color using RGB values. 
                // Each value has a range of 0-255.
                mySolidColorBrush.Color = Color.FromArgb(255, 0, 0, (byte)height);
                myRgbRectangle.Fill = mySolidColorBrush;

                myCanvas.Children.Add(myRgbRectangle);
                Canvas.SetTop(myRgbRectangle, j);
                Canvas.SetLeft(myRgbRectangle, i);

And it's throwing this error: Specified Visual is already a child of another Visual or the root of a CompositionTarget.

Answer

Mark Hall picture Mark Hall · Oct 6, 2012

You need to use a Canvas istead of a Grid. You use coordinates to position elements in a Canvas versus Column and Row in a Grid.

Definition of a Canvas:

Defines an area within which you can explicitly position child elements by using coordinates that are relative to the Canvas area.

You would then use Canvas.SetTop and Canvas.SetLeft Properties like this (assuming that your canvas is named myCanvas):

 myCanvas.Children.Add(myRgbRectangle);
 Canvas.SetTop(myRgbRectangle, 50);
 Canvas.SetLeft(myRgbRectangle, 50);

Edit

Based on your edit, it is like I said you are adding the same rectangle more than once. You need to be creating it in your For Loop each time you add it. Something like this.

for (int i = 0; i < ElevationManager.Instance.heightData.GetLength(0); i++) 
    for (int j = 0; j < ElevationManager.Instance.heightData.GetLength(1); j++) 
    { 
        Rectangle rect = new Rectangle();
        rect.Width = 1;
        rect.Height = 1;
        height = ElevationManager.Instance.heightData[i, j] / 100; 
        // Describes the brush's color using RGB values.  
        // Each value has a range of 0-255. 
        mySolidColorBrush.Color = Color.FromArgb(255, 0, 0, (byte)height); 
        rect.Fill = mySolidColorBrush; 

        myCanvas.Children.Add(rect); 
        Canvas.SetTop(rect, j); 
        Canvas.SetLeft(rect, i); 
    }