I have a 2D array that contains rectangles. They are stored in a dynamic UniformGrid. How do I find out which rectangle in the array was MouseDown?
I tried this but I keep getting [0,0]:
if (e.OriginalSource is Shape s)
{
cellRow = (int)s.GetValue(Grid.RowProperty);
cellColumn = (int)s.GetValue(Grid.ColumnProperty);
rectangle[cellRow,cellColumn].Fill = new SolidColorBrush(Colors.Black);
}
And this is how I generated the rectangles:
rectangle = new Rectangle[rowcol, rowcol];
for (int x = 0; x < rowcol; x++)
{
for (int y = 0; y < rowcol; y++)
{
rectangle[y, x] = new Rectangle { Stroke = Brushes.Black, StrokeThickness = 0.5, Fill = Brushes.White };
GameUniformGrid.Children.Add(rectangle[y, x]);
}
}
The MouseDown event in xaml:
<UniformGrid x:Name="GameUniformGrid" HorizontalAlignment="Left" Height="272" VerticalAlignment="Top" Width="272" Grid.Row="0" Grid.Column="0" Rectangle.MouseDown="ToggleGrid"/>
I think the problem is with initializing a rectangle,
When you work with multidimentional array you have some rows and column and what you are doing is using row only in both row,column.
What if rowcol =0 ? the loop will not run because this condition.
x < rowcol (0<0);
You should
rectangle = new Rectangle[row, col];
for (int x = 0; x < row; x++)
{
for (int y = 0; y < col; y++)
{
rectangle[y, x] = new Rectangle { Stroke = Brushes.Black, StrokeThickness = 0.5, Fill = Brushes.White };
GameUniformGrid.Children.Add(rectangle[y, x]);
}
}
(For example)
where row = 2 ,col =2
Related
I have create a ListView and get a data from a ListView to draw a rectangle.
The ListView items count is always change with unknown count and also the x and y too. My ListView will be like this :
Subitem[0].Text || Subitem[1].text
500 100
100 200
++ ++
By Subitem[0] is X ,Subitem[1] is Y
And now I have create a code to draw the rectangle like this:
private void Draw_Tick(object sender, EventArgs e)
{
this.Invalidate();
Pen p = new Pen(Color.Red);
SolidBrush sb = new SolidBrush(Color.Red);
Graphics g = PaintingPanel.CreateGraphics();
for (int i = 0; i < ListView1.Items.Count + 1; i++)
{
p.Width = 3;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.InterpolationMode = InterpolationMode.Low;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
Rectangle rectf = new Rectangle(X.Split(',')[i],Y.Split(',')[i], 50, 75);
g.DrawRectangle(p,rectf);
}
}
Add the X and Y to Array
Public static string X;
Public static string Y;
for (int i = 0; i < ListView1.Items.Count + 1; i++)
{
List<string> ls = new List<string>();
foreach (ListViewItem item in ListView1.Items)
{
ls.Add(item.SubItems[0].Text);
}
X = string.Join(",", ls);
}
for (int i = 0; i < ListView1.Items.Count + 1; i++)
{
List<string> ls2 = new List<string>();
foreach (ListViewItem item in ListView1.Items)
{
ls2.Add(item.SubItems[1].Text);
}
Y = string.Join(",", ls2);
}
But my point is I have used this.Invalidate() to clear the drawing and create a new drawing because the data changed. My question is how can I just move the rectangle instead of using this.invalidate to clear the drawing (Because its kind of flashing when this.Invalidate();.
My goal is to have a robot use this grid to create a map base off the information it collects from its surroundings. When the robot detects an object the square in front of it turns red. Currently I am stuck on how I can give each square an x and Y value for location purposes. Also when I scroll the screen the block sizes change, can someone provide help with that as well?
Rectangle rect = new Rectangle(700, 350, 50, 50);
g.DrawRectangle(myPen, rect); // Draws the Rectangle to the screen
e.Graphics.FillEllipse(myBrush, 700,350,50,50);`
for (int i = 0; i < 9900; i = i + 50)
{
rect = new Rectangle(0 + i, 0, 50, 50);
g.DrawRectangle(myPen, rect);
for (int j = 0; j < 9900; j = j + 50)
{
rect = new Rectangle(0 + i, 0 + j, 50, 50);
g.DrawRectangle(myPen, rect);
}
}
Here is a very quick example of how to do this using a 2d array. It was written in LINQPad, so it may look a little odd, but it should give you some leads. It allows you to store a map and look up values using x and y coordinates. You can use the CellInfo class to add any extra information about the cell that you need, beyond if it is blocking or not.
Ideally, you would want to wrap the entire array up in your own Map class, that abstracts away the details, and gives you a lot of helpful utility functions. For instance, if your map is extremely large, you may run out of memory. You could have the Map class only load smaller blocks of the map from files on disk as needed, or even make the map wrap around its self easily.
void Main()
{
var map = new CellInfo[10, 10];
for (int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
map[x, y] = new CellInfo();
}
}
var rnd = new Random();
for (int i = 0; i < 20; i++)
{
map[rnd.Next(0, 10), rnd.Next(0, 10)].IsBlocked = true;
}
DrawMap(map).Dump();
}
public Bitmap DrawMap(CellInfo[,] map)
{
var img = new Bitmap(320, 320, PixelFormat.Format32bppArgb);
using (var g = Graphics.FromImage(img))
{
for (int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
var cell = map[x, y];
Brush brush = cell.IsBlocked ? Brushes.Red : Brushes.White;
g.FillRectangle(brush, x * 32, y * 32, 31, 31);
g.DrawRectangle(Pens.Black, x * 32, y * 32, 31, 31);
}
}
}
return img;
}
public class CellInfo
{
public bool IsBlocked { get; set; } = false;
}
It produces the following output (varies each time it is run):
I have listview in form1 and in print preview I use the below code to get the column but the text on the listview are on the right when I view them in the print preview..
They are on the right please help me how to make them on the right when the print preview display.
int[] X = { 40, 100, 160, 540, 650 }; //relative to Left margin510
int Y = 450; //relative to Top margin
Font F = listView3.Font;
Brush B = new SolidBrush(listView3.ForeColor);//
for (int I = 0; I < listView3.Items.Count; I++)
{
for (int J = 0; J < listView3.Items[I].SubItems.Count; J++)
{
e.Graphics.DrawString(listView3.Items[I].SubItems[J].Text, F, B, X[J], Y );//
}
Y += F.Height;
}
So I'm creating a 2d grid with drawings of rectangles and circles inside of a
flowLayoutPanel. The problem I'm getting however is that they are not being drawn completely.
This is the code of the event when a button is pushed.
private void DrawIt()
{
System.Drawing.Graphics graphics = flowLayoutPanel1.CreateGraphics();
graphics.Clear(Form1.ActiveForm.BackColor);
int row = Convert.ToInt32(textBox1.Text);
int column = Convert.ToInt32(textBox2.Text);
flowLayoutPanel1.Width = (row * 50) + 30;
flowLayoutPanel1.Height = (column * 50) + 1;
for (int j = 0; j < column; j++)
{
for (int i = 0; i < row; i++)
{
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(50 * i, 50*j, 50, 50);
graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}
}
}
I make each rectangle the size of 50 px so I know how big to calculate the width and height. I even added some extra in case I messed up. But in the end I get the following:
Any ideas on what could be the problem?
You create the graphics from the panel and then change its size. The graphics object therefore clips to the previous size.
Change the size before you create the graphics object:
int row = Convert.ToInt32(textBox1.Text);
int column = Convert.ToInt32(textBox2.Text);
flowLayoutPanel1.Width = (row * 50) + 30;
flowLayoutPanel1.Height = (column * 50) + 1;
System.Drawing.Graphics graphics = flowLayoutPanel1.CreateGraphics();
graphics.Clear(Form1.ActiveForm.BackColor);
for (int j = 0; j < column; j++)
{
for (int i = 0; i < row; i++)
{
System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(50 * i, 50 * j, 50, 50);
graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
}
}
I'm trying to make a little game in C# using WPF. In one of my Modelclasses I have a Map, which is a 2D-array filled with Enumeration objects. Each of these objects represents a type of tile.
In my View these Tiles need to be converted to an Image and the image needs to be set to the right coordinates in the Grid.
How do I bind the array to the Grid or the Images in the view so that it will auto-update when the array changes?
This how it works now:
Enumeration that's used to fill the array:
public enum Tile { FLOOR, WALL, DESTINATION, EMPTY }
Method to create and position all the Images (this is in the code-behind):
public void LoadMap(Map mapModel)
{
Tile[,] tiles = mapModel.TileMap;
int nRows = tiles.GetLength(1);
int nCols = tiles.GetLength(0);
for (int i = 0; i < nCols; i++)
{
ColumnDefinition col = new ColumnDefinition();
map.ColumnDefinitions.Add(col);
}
for (int i = 0; i < nRows; i++)
{
RowDefinition row = new RowDefinition();
map.RowDefinitions.Add(row);
}
for (int y = 0; y < nCols; y++)
{
for (int x = 0; x < nRows; x++)
{
Image img = new Image();
switch (tiles[y, x])
{
case Tile.FLOOR:
img.Source = _srcFloor;
break;
case Tile.WALL:
img.Source = _srcWall;
break;
case Tile.DESTINATION:
img.Source = _srcDestination;
break;
case Tile.EMPTY:
img.Source = _srcEmpty;
break;
}
img.SetValue(Grid.ColumnProperty, x);
img.SetValue(Grid.RowProperty, y);
map.Children.Add(img);
}
}
}
XAML:
<Grid Name="map">
</Grid>
And here is a screenshot of how it looks: