I'm trying to fill a rectangle with a variable quantity of little rectangles but adjusting the distance between them depending on the number of units (more units->the lesser the distance between).
I'm a newbie programming WPF in C# and i don´t know how to advance from this point.
How can I do it?
The code so far:
int units = 20;
int width = 10;
int height = 20;
int top = 200;
int left = 200;
int rectangleWidth = 300;
int rectangleHeight = 100;
for (int i = 0; i < units; i++)
{
Rectangle rec = new Rectangle()
{
Width = width,
Height = height,
Fill = Brushes.Black,
Stroke = Brushes.White,
StrokeThickness = 1,
RadiusX = 3,
RadiusY = 3,
};
cuadernodibujo.Children.Add(rec);
Canvas.SetTop(rec, top);
Canvas.SetLeft(rec, left + (i*50));
}
I have updated the code, but doesn´t work.
I don´t know what am i doing wrong.
The piece of code so far:
int rectangleWidth = 500;
int rectangleHeight = 100;
int units = 60;
int unitsX = 10;
int unitsY = 6;
var childWidht = (rectangleWidth - 2*Left) / unitsX;
var childHeigth = (rectangleHeight - 2*Top ) / unitsY;
int width = 10;
int height = 20;
double top = 100;
double left = 100;
for (int i = 0; i < units; i++)
{
Rectangle rec = new Rectangle()
{
Width = width,
Height = height,
Fill = Brushes.Black,
Stroke = Brushes.White,
StrokeThickness = 1,
RadiusX = 3,
RadiusY = 3,
};
cuadernodibujo.Children.Add(rec);
for (int j = 0; j < unitsY; j++)
{
Rectangle rec2 = new Rectangle()
{
Width = width,
Height = height,
Fill = Brushes.Black,
Stroke = Brushes.White,
StrokeThickness = 1,
RadiusX = 3,
RadiusY = 3,
};
cuadernodibujo.Children.Add(rec2);
Canvas.SetTop(rec, top + (j * childHeigth));
for (int k = 0; k < unitsX; k++)
{
Rectangle rec3 = new Rectangle()
{
Width = width,
Height = height,
Fill = Brushes.Black,
Stroke = Brushes.White,
StrokeThickness = 1,
RadiusX = 3,
RadiusY = 3,
};
cuadernodibujo.Children.Add(rec3);
Canvas.SetLeft(rec, left + (k * childWidht));
}
}
}
If I understand correctly, you want to spread the little rectangles uniformly over the width of the parent rectangle.
This is less a programming problem, then a maths problem.
Given the parent rectangle's width parentWidht and the number of child rectangles units each child rectangle has a width of:
var childWidht = parentWidht / units;
If you want to add a left and right margin (given your left variable), you need to subtract the margin from parentWidht.
var childWidht = (parentWidht - 2 * left) / units; // 2 times left, to add the margin on both sides.
This gives you the width of each child, you now only have to move each child rectangle according to the previously calculated childWidht.
...
var childWidht = (parentWidht - 2 * left) / units;
for (int i = 0; i < units; i++)
{
...
Canvas.SetLeft(rec, left + (i*childWidht));
}
Update to question in the comments
With that I can fill a single line, but how can I fill the rest of the lines (to fill the parent height as well)?
We can apply the same logic as for the horizontal filling.
First calculate the child rectangles height (parentHeight - 2 * top)
Then wrap the horizontal rectangles into a loop and move each line according to the calculated height.
Here the listing with horizontal and vertical filling.
...
var childWidht = (parentWidht - 2 * left) / unitsX;
var childHeigth = (parentHeigth - 2 * top) / unitsY;
for (int j = 0; j < unitsY; i++) // first loop for vertical filling
{
for (int i = 0; i < unitsX; i++) // second loop for horizontal
{
var rect = new Rectangle { ... } ;
Canvas.Children.Add(rect); // Only add once in the inner loop.
Canvas.SetTop(rec, top + (j * childHeigth)); // here we use j, the vertical index
Canvas.SetLeft(rec, left + (i*childWidht)); // here we use i, the horizontal index
}
}
Related
I am unable to get the ScrollBars to appear for a Canvas when its children are out of view. This is being directly added to the MainWindow.
<ScrollViewer>
<Canvas x:Name="MainCanvas"/>
</ScrollViewer>
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
for (int i = 0; i < 20; i++)
{
var rect = new Rectangle()
{
Height = 100,
Width = 200,
Stroke = new SolidColorBrush(Colors.Magenta)
};
Canvas.SetLeft(rect, (i * 200) + 10);
Canvas.SetTop(rect, 10);
var rect1 = new Rectangle()
{
Height = 100,
Width = 200,
Stroke = new SolidColorBrush(Colors.DarkOrchid)
};
Canvas.SetLeft(rect1, 10);
Canvas.SetTop(rect1, (i * 100) + 10);
MainCanvas.Children.Add(rect);
MainCanvas.Children.Add(rect1);
}
}
So, children are being added that go out of view horizontally and vertically. I've tried various settings for scrollbar visibility, alignments, etc. but just cant get the scrollbars to appear. Thanks for any inputs.
Specify a size for the Canvas so the ScrollViewer can measure it:
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
MainCanvas.Width = 0;
MainCanvas.Height = 0;
for (int i = 0; i < 20; i++)
{
var rect = new Rectangle()
{
Height = 100,
Width = 200,
Stroke = new SolidColorBrush(Colors.Magenta)
};
double left = (i * 200) + 10;
MainCanvas.Width = left;
Canvas.SetLeft(rect, left);
Canvas.SetTop(rect, 10);
var rect1 = new Rectangle()
{
Height = 100,
Width = 200,
Stroke = new SolidColorBrush(Colors.DarkOrchid)
};
double top = (i * 100) + 10;
MainCanvas.Height = top;
Canvas.SetLeft(rect1, 10);
Canvas.SetTop(rect1, top);
MainCanvas.Children.Add(rect);
MainCanvas.Children.Add(rect1);
}
}
You may also want to enable horizontal scrolling:
<ScrollViewer HorizontalScrollBarVisibility="Auto">
...
I'm generating a barcode depending on how many inputs that the user set in the numericUpDown control. The problem is when generating a lot of barcodes, the other barcodes cannot be seen in the printpreviewdialog because it I cannot apply a nextline or \n every 4-5 Images.
int x = 0, y = 10;
for (int i = 1; i <= int.Parse(txtCount.Text); i++)
{
idcount++;
connection.Close();
Zen.Barcode.Code128BarcodeDraw barcode = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum;
Random random = new Random();
string randomtext = "MLQ-";
int j;
for (j = 1; j <= 6; j++)
{
randomtext += random.Next(0, 9).ToString();
Image barcodeimg = barcode.Draw(randomtext, 50);
resultimage = new Bitmap(barcodeimg.Width, barcodeimg.Height + 20);
using (var graphics = Graphics.FromImage(resultimage))
using (var font = new Font("Arial", 11)) // Any font you want
using (var brush = new SolidBrush(Color.Black))
using (var format = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Far}) // Also, horizontally centered text, as in your example of the expected output
{
graphics.Clear(Color.White);
graphics.DrawImage(barcodeimg, 0, 0);
graphics.DrawString(randomtext, font, brush, resultimage.Width / 2, resultimage.Height, format);
}
x += 25;
}
e.Graphics.DrawImage(resultimage, x, y);
}
There's no "new lines" in rasterized graphics. There's pixels. You've got the right idea, every n number of images, add a new line. But since you're working with pixels, let's say every 4 images you're going to need to add a vertical offset by modifying the y coordinate of all your graphics draw calls. This offset, combined with a row height in pixels could look something like this:
var rowHeight = 250; // pixels
var maxColumns = 4;
var verticalOffset = (i % maxColums) * rowHeight;
Then, when you can supply a y coordinate, starting at or near 0, add the vertical offset to it.
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);
}
}
Currently, I have a random terrain generator, which I am sure works properly, however, when I attempt to build a set of VertexPositionColor, it does not render properly. This is what I currently have (overhead view):
My code:
List<VertexPositionColor> w = new List<VertexPositionColor>();
int width = 20;
int height = 20;
float terrainScale = 2.0f;
long seed = (DateTime.Now.Millisecond + DateTime.Now.Second * DateTime.Now.Hour);
ProceduralLayeredMapGenerator plmg = new ProceduralLayeredMapGenerator(seed);
Random rand = new Random((int)seed);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
Vector3 position = new Vector3();
position.X = x;//(x - width / 2) * terrainScale;
position.Z = y;//(y - height / 2) * terrainScale;
float point = plmg.getPoint(x, y);
Color computedColor = new Color(rand.Next(255), rand.Next(255), rand.Next(255));
position.Y = (point * 2);
w.Add(new VertexPositionColor(position, computedColor));
}
}
colors = w.ToArray();
And then the drawing code:
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, colors, 0, colors.Length / 3, VertexPositionColor.VertexDeclaration);
}
How can I get it to look something more like this:
If you want to draw a TriangleStrip then you must add the vertices in the order in which they will be used to draw the triangles; right now you're adding vertices top-to-bottom, left-to-right. Also, to render a height map like that you'll need to use multiple TriangleStrips.
I am trying to create rectangles and the number of rectangles is depend on data passed from database.
For example, if number = 5, the program will generate 5 rectangles. Also, these rectangles must be able to follow my rectangle property settings, like height, width,color...put them in one line at the end.
Is there a way to do that?
I am using WPF and C#.
Thank you.
To create the rectangle in code dynamically:
int number = 5;
int width = 10;
int height = 10;
int top = 20;
int left = 20;
for (int i = 0; i < number; i++)
{
// Create the rectangle
Rectangle rec = new Rectangle()
{
Width = width,
Height = height,
Fill = Brushes.Green,
Stroke = Brushes.Red,
StrokeThickness = 2,
};
// Add to a canvas for example
canvas.Children.Add(rec);
Canvas.SetTop(rec, top);
Canvas.SetLeft(rec, left);
}