List of labels does not display in Picture Box - c#

I have a problem with Labels in VisulaStudio.
The version of VisualStudio I use is 2012.
The problem is, I need to show a grid and label the lines. The code I wrote seams identical to the solution of a similar problem here. It doesn't give me any compiler errors, but the labels still do not display in the pictureBox.
private void aResize()
{
Size clientSize = this.ClientSize;
int hToDraw, wToDraw;
hToDraw = clientSize.Height - 2 * marginOfTab;
wToDraw = clientSize.Width - 2 * marginOfTab;
tabControl1.Size = new Size(wToDraw, hToDraw);
piB1.Size = new Size(wToDraw, hToDraw);
piB1.Image = new Bitmap(piB1.Size.Width, piB1.Size.Height);
using (Graphics g = Graphics.FromImage(piB1.Image))
{
g.FillRectangle(new SolidBrush(Color.LightGray), 0, 0, W, H);
Pen gridPen = new Pen(Color.White, 1f);
int hDrawingStep = hToDraw / 10 -1;
int wDrawingStep = wToDraw / 10 -1;
for (int local = 1; local < 11; local++)
{
g.DrawLine(gridPen, 0, hDrawingStep*local, wToDraw, hDrawingStep*local); //horizontal axix
g.DrawLine(gridPen, wDrawingStep*local, 0, wDrawingStep*local , hToDraw); //vertical axis
Label localLabel = new Label();
localLabel.Name = "la" + local;
localLabel.Visible = true;
localLabel.Text = (local*100).ToString();
localLabel.Location = new Point((int)local*hDrawingStep, (int)10);
labelList.Add(localLabel);
}
}
}
All variables which are not declared in the code above are declared earlier. I didn't want to paste in too much. Thanks for any suggestion.

You don't set any parent for your localLabel, so how could it be rendered? Try this right before adding your localLabel to your labelList:
//...
localLabel.Parent = piB1;
labelList.Add(localLabel);

Related

Creating a Mosaic out of multiple images increases the luminance of the final image

I am trying to create a collage of images with Magick.net. I am using MagickImageCollection and .Mosaic(). I tried already a few of the functions provided by MagickImageCollection but all of them increase the brightness of the final image. The only one that worked so far was .Montage(), but with .Montage() I don't get the padding right.
How do I need to configure it, that .Mosaic() keeps the colors as they are in the single images?
using (var collection = new MagickImageCollection())
{
for (var i = 0; i < thumbnailCount; i++)
{
var image = new MagickImage(TempThumbPathFor(i));
image.Resize(256, 0);
var posX = (image.Page.Width + margin) * (i % 2);
var posY = (image.Page.Height + margin) * (i / 2);
image.Page = new MagickGeometry(posX, posY, new Percentage(100), new Percentage(100));
collection.Add(image);
}
using (var result = collection.Mosaic())
{
result.Write(newPath);
}
}
Collage of images with washed out colors:
For more information why the problem occurred in the first place have a look at this issue: GitHub
Figured out how to create a montage with padding and proper color. Couldn't get it to work with .Mosaic but with .Montage().
The important part is to add the margin to X, Y, Height and Width and call .Trim() on the final image. You will most likely have to play around a bit with the margin to get a balanced looking padding between the images, but other than that it works quite well.
const int margin = 2;
MagickGeometry geometry = null;
using (var collection = new MagickImageCollection())
{
for (var i = 0; i < thumbnailCount; i++)
{
var image = new MagickImage(TempThumbPathFor(i));
image.Resize(256, 0);
collection.Add(image);
if (i == 0)
{
geometry = image.BoundingBox;
geometry.X += margin;
geometry.Width += margin;
geometry.Y += margin;
geometry.Height += margin - 1;
}
}
using (var result = collection.Montage(new MontageSettings()
{
Geometry = geometry,
BackgroundColor = MagickColor.FromRgb(255, 255, 255)
}))
{
result.Trim();
result.Write(newPath);
}
}

How to use DataGridViewImageColumn to display images using zoom and also keeping the aspect ratio?

My code
Building the column
IconColumn = new DataGridViewImageColumn()
{
Name = "Icon",
HeaderText = "Icon",
SortMode = DataGridViewColumnSortMode.NotSortable,
Width = 50,
ImageLayout = DataGridViewImageCellLayout.Stretch,
Resizable = DataGridViewTriState.False
};
IconColumn.DefaultCellStyle.NullValue = null;
IconColumn.CellTemplate = new ClockDataGridViewIconCell();
Setting an icon
float maxHeight = 200;
float maxWidth = 200;
var r = new Rectangle(0,
0,
(int)Math.Round(maxWidth),
(int)Math.Round(maxHeight)
);
MyClockData.Icon = Utils.ResizeToFitBoundingBox(
new Bitmap(fd.FileName),
r);
The ResizeToFitBoundingBox method
internal static Bitmap ResizeToFitBoundingBox(Image image, in Rectangle box)
{
float maxHeight = box.Width;
float maxWidth = box.Height;
float x = Math.Min(maxWidth / image.Width,
maxHeight / image.Height);
float newW = (float)image.Width * x;
float newH = (float)image.Height * x;
var bmp = new Bitmap((int)Math.Round(maxWidth),
(int)Math.Round(maxHeight));
bmp.MakeTransparent();
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.DrawImage(image, (bmp.Width - newW) / 2,
(bmp.Height - newH) / 2, newW, newH);
}
return bmp;
}
Example icon
I have tried all the 4 possible values for DataGridViewImageColumn.ImageLayout and the cell looks the same:
Normal
Not Set
Stretch
Zoom
None of them Works for what I wish. The official documentation is here. I would like the same behaviour as Forms.ImageLayout.Zoom.
Note: I use .NET Framework v4.6.1.
I solved the problem by adding this line:
IconColumn.ImageLayout = DataGridViewImageCellLayout.Zoom;
after each statement which adds or updates an icon in the DataGridView.
It seems that setting this property to the same value as before repaints the icons in the column in the way the value of the property suggests.

Adding a label programmatically in C#

I am trying to create a paddle using a label which must be done programmatically to a brick breaker game and my aim is so that no matter what desktop computer with different screen sizes I'm using, the paddle will always be in the bottom center of the screen but for some reason the paddle(label) is not showing. This is the code I'm using:
Screen userScreen = Screen.PrimaryScreen;
int screenWidth = userScreen.WorkingArea.Width;
int screenHeight = userScreen.WorkingArea.Height;
this.Width = screenWidth;
this.Height = screenHeight;
Label lblPaddle = new Label();
lblPaddle.BackColor = Color.White;
lblPaddle.BorderStyle = BorderStyle.FixedSingle;
//lblPaddle.Left = (this.ClientSize.Width - lblPaddle.Width) / 2;
//lblPaddle.Top = (this.ClientSize.Height - lblPaddle.Height) / 2;
//lblPaddle.Size = this.ClientSize;
int lblPaddleWidth = (int)(screenWidth * 0.15);
int lblPaddleHeight = lblPaddle.Height;
int lblPaddleXCoord = (screenWidth / 2) - (lblPaddleWidth / 2);
int lblPaddleYCoord = screenHeight - lblPaddleHeight - (int)(screenHeight * 0.1);
lblPaddle.SetBounds(lblPaddleXCoord, lblPaddleYCoord, lblPaddleWidth, lblPaddleHeight);
this.Controls.Add(lblPaddle);
The part where there are comments were different approaches I attempted in order to try and make it work.
Why is it not showing?
I have absolutely no problems with your code when called like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitLabel();
}
private void InitLabel()
{
Screen userScreen = Screen.PrimaryScreen;
int screenWidth = userScreen.WorkingArea.Width;
int screenHeight = userScreen.WorkingArea.Height;
this.Width = screenWidth;
this.Height = screenHeight;
// I added the following 2 lines because the form was below the task bar
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(0,0);
Label lblPaddle = new Label();
lblPaddle.Name = "lblPaddle";
lblPaddle.BackColor = Color.White;
lblPaddle.BorderStyle = BorderStyle.FixedSingle;
int lblPaddleWidth = (int)(screenWidth * 0.15);
int lblPaddleHeight = lblPaddle.Height;
int lblPaddleXCoord = (screenWidth / 2) - (lblPaddleWidth / 2);
int lblPaddleYCoord = screenHeight - lblPaddleHeight - (int)(screenHeight * 0.1);
lblPaddle.SetBounds(lblPaddleXCoord, lblPaddleYCoord, lblPaddleWidth, lblPaddleHeight);
this.Controls.Add(lblPaddle);
}
}
It ends up looking like this:
EDIT: If you're planning to do anything with it, I suggest giving it a name. I added it above.
For some odd reason this was not working. I spoke with a lecturer at my school and she also could not figure out what the problem was. Perhaps it was a bug of some sort. The only way I managed to resolve this was by creating another form and create another paddle and then I copied the code from the form I created to the original and it worked. Neither me nor the lecturer could figure out what the problem was. It was just plain weird since the code was basically the same.

Setting LayoutTransform to RotateTransform for elements on a Canvas yields unexpected results

From within MainWindow ctor :
for(var i = 0; i <5; i++)
{
var button = new Button {};
button.LayoutTransform = new RotateTransform(i * 10);
button.Width = 300;
button.Height = 300;
TempCanvas.Children.Add(button);
}
This produces the following:
Please can someone explain why this is happening. I am expecting the 5 buttons to be rotated through the same point.
I did not want to RenderTransform as the graphics that I will be rendering would be drawn outside of the parent and not reflected in the measure.
The Canvas is the issue, unlike other contains it is not constrained in its physical size, it stretches out to infinity in all directions. Therefore it's rotation origin is not the canvas.width/2 by canvas.height/2.
If you repeat your code in a grid or dockpanel you will get the required result.
Do you want something like this:
Code:
for (var i = 0; i < 5; i++)
{
var button = new Button { };
//button.LayoutTransform = new RotateTransform(i * 10);
button.RenderTransform = new RotateTransform(i * 10);
button.Width = 300;
button.Height = 300;
button.Margin = new Thickness(200, 0, 0, 0);
TempCanvas.Children.Add(button);
}

Seat reserving software: Drawing lots of Seats in C# instantly

I'm building Seat reserving software using C# and I am confusing how I draw lots of seats instantly.
I'm trying three way which is..
Using Usercontrol
public void DrawUsercontrol(int x, int y)
{
int space = 4;
int SeatLimit = 165;
int RowSeatLimit = 15;
for (var i = 1; i < SeatLimit; i++)
{
UserControl1 ctrl = new UserControl1();
ctrl.Size = new System.Drawing.Size(25, 25);
ctrl.Location = new Point(x + space, y);
if (i % RowSeatLimit == 0)
{
x = 1;
y = y + 25 + space;
}
x = x + 25 + space;
ctrl.label1.Text = i.ToString();
ctrl.label1.Click += new EventHandler(label1_Click);
panel1.Controls.Add(ctrl);
}
}
Using "Panel" control
public void DrawingPanel(int x, int y)
{
Panel myPanel = new Panel();
int width = 16;
int height = 16;
myPanel.Size = new Size(width, height);
myPanel.BackColor = Color.White;
myPanel.Location = new Point(x, y);
Label mylabel = new Label();
mylabel.Text = "4";
myPanel.Controls.Add(mylabel);
myPanel.BackColor = Color.YellowGreen;
// this.Controls.Add(myPanel);
panel1.Controls.Add(myPanel);
}
Using Graphics and draw Rectangle
public void DrawingSquares(int x, int y)
{
SolidBrush myBrush = new SolidBrush(System.Drawing.Color.Red);
Graphics graphicsObj;
graphicsObj = this.panel1.CreateGraphics();
Rectangle myRectangle = new Rectangle(x, y, 30, 30);
graphicsObj.FillRectangle(myBrush, myRectangle);
graphicsObj.Dispose();
}
I refer first option but it's too slow.
And how can I decide?
Your problem is that you are adding only one control at a time. Adding a control forces a full refresh (software GDI+ rendering is quite slow) of the parent panel (best case) and perhaps the whole form (worst case).
Try creating all your controls and adding them in one line using Panel.Controls.AddRange. This will only prompt one refresh.
You should also only add these controls when the form is first shown and when the number of seats change - it is an expensive (and relatively slow) operation.
Consider creating a UserControl for each seat so that you don't have to manage the seat labels and seat borders separately - this way you can just have one list. If you add the seats in order, the index of an item in the list will map to its seat number! You probably wont get a performance increase from this but your code will be easier to work with.

Categories

Resources