.NET C# - WinForm border - c#

I have a WinForm without a border (borderless). How can I add a 1px black border to the form?
public MainForm()
{
InitializeComponent();
this.DoubleBuffered = true;
Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 10, 10)); // adjust these parameters to get the lookyou want.
}
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect, // x-coordinate of upper-left corner
int nTopRect, // y-coordinate of upper-left corner
int nRightRect, // x-coordinate of lower-right corner
int nBottomRect, // y-coordinate of lower-right corner
int nWidthEllipse, // height of ellipse
int nHeightEllipse // width of ellipse
);
I need a borderless form but I want to add a 1px border.

In the Paint event handler of the form, add this code:
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(0, 0, Width - 1, Height - 1));
}
Good luck!

You could add a fully docked Panel, and another fully docked Panel as a child control. Set the padding of the outer Panel to 1 and the background color of the outer Panel to black.
Then set the background color of the inner Panel to SystemColors.Control.

If you don't want to paint,
Add 4 panels width or height 2 or 4 and black background colour
after dock them in 4 sides differently on top, right, bottom, left respectively
this.FormBorderStyle = FormBorderStyle.None;
Panel pnlTop = new Panel() { Height = 4, Dock = DockStyle.Top, BackColor = Color.Green };
this.Controls.Add(pnlTop);
Panel pnlRight = new Panel() { Width = 4, Dock = DockStyle.Right, BackColor = Color.Green };
this.Controls.Add(pnlRight);
Panel pnlBottom = new Panel() { Height = 4, Dock = DockStyle.Bottom, BackColor = Color.Green };
this.Controls.Add(pnlBottom);
Panel pnlLeft = new Panel() { Width = 4, Dock = DockStyle.Left, BackColor = Color.Green };
this.Controls.Add(pnlLeft);
You can also change their mouse pointer to resize icons also you can resize the form writing some code on mouse events.

Related

Center a Panel within a Panel, which is in a TableLayoutPanel, in C#

So basically I've got a game board going, represented by a TableLayoutPanel. Each cell of the TableLayoutPanel represents a space on the board and contains a Panel. Each Panel has a Label in it to display what is currently in that space (e.g. a character or building) and its BackColor represents what kind of terrain that space is (e.g. Land, Water, etc.). When the player attempts to move a character, each possible space that that character can move will become "highlighted." The player will then double click one of the highlighted spaces to move the character there.
In order to highlight a space, I add a Panel to the existing Panel (the one that already has a Label in it).
So to recap, TableLayoutPanel --> Panel --> Label, Panel.
The main problem I'm having is that I can't get the "highlight-Panel" to center within its parent Panel; it's always Top-Left Centered. I want to be able to see part of the BackColor of the parent Panel in order to make it easier for the player to decide where to go. Thus, setting Dock to Fill is not an option. The highlight-Panel is slightly smaller than the parent Panel, thereby allowing for the edges of the parent Panel's BackColor to be visible. Yes, Anchor is set to None.
The secondary problem is that I cannot get any of the Labels' text colors to change. I've tried changing it at initialization or more directly with a specific location using "tableLayoutPanel.GetControlFromPosition(16, 4).Controls[0].ForeColor = Color.White;" but nothing seems to work.
To be honest, I'm not interested in super complicated hack fixes. But if there's something simple or something I missed, I'd really appreciate some input. Thanks.
This is the code that creates the TableLayoutPanel, the Panels within that, and the Labels within each Panel:
// Create TableLayoutPanel to hold Panels
tableLayoutPanel = new TableLayoutPanel()
{
RowCount = 1,
ColumnCount = 1,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
Location = new Point(12, 12),
Dock = DockStyle.Fill,
AutoScroll = true,
};
// Add tableLayoutPanel to the form
this.Controls.Add(tableLayoutPanel);
// Reset and add rows/columns + styles
tableLayoutPanel.RowStyles.Clear();
tableLayoutPanel.ColumnStyles.Clear();
for (int i = 0; i < rows; i++)
{
tableLayoutPanel.RowCount++;
tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
}
tableLayoutPanel.RowCount--;
for (int j = 0; j < cols; j++)
{
tableLayoutPanel.ColumnCount++;
tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
}
tableLayoutPanel.ColumnCount--;
// Add Panels to TableLayoutPanel
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
// Create new Panel
Panel space = new Panel()
{
BackColor = SystemColors.ActiveCaption,
BorderStyle = BorderStyle.FixedSingle,
Margin = new Padding(0),
Size = new Size(45, 45)
};
space.MouseClick += new MouseEventHandler(clickOnSpace);
// Create new Label
Label info = new Label()
{
Size = new Size(93, 93),
Text = "Info",
Dock = DockStyle.Fill,
TextAlign = ContentAlignment.MiddleCenter,
Enabled = false,
Font = new Font("Microsoft Sans Serif", 6),
ForeColor = Color.White
};
// Add Label to Panel
space.Controls.Add(info);
// Add Panel to TableLayoutPanel
tableLayoutPanel.Controls.Add(space, j, i);
}
}
And the code that creates the highlight-Panel:
// Highlight potential positions using possibleMoves
private void Highlight(List<Tuple<int, int>> possibleMoves, int remaining)
{
int r = 0;
int c = 0;
foreach (Tuple<int, int> pair in possibleMoves)
{
r = pair.Item1;
c = pair.Item2;
// If highlight-Panel doesn't already exist
if (tableLayoutPanel.GetControlFromPosition(c, r).Controls.Count == 1)
{
// Create a Panel to highlight the space
Panel highlight = new Panel()
{
Name = "highlight",
Size = new Size(30, 30),
BackColor = Color.Yellow,
Anchor = AnchorStyles.None
};
highlight.MouseDoubleClick += new MouseEventHandler(doubleClickOnSpace);
// Add highlight Panel to space Panel
tableLayoutPanel.GetControlFromPosition(c, r).Controls.Add(highlight);
// Bring highlight Panel to front
tableLayoutPanel.GetControlFromPosition(c, r).Controls[1].BringToFront();
}
}
}
... Thus, setting Dock to Fill is not an option.
In fact I believe setting Dock to Fill is really a good option!
Take a look at this image. It's a TableLayoutPanel having 2 columns and 2 rows. And each cell contains a Pannel which contains a Panel which contains a Label. Despite what you expect Dock property of all controls has been set to Fill!
I tell you settings for the first cell which you can see Red, Black and White colors in it.
The cell contains:
Red area, a Panel having:
○ BackColor property set to Red
○ Margin property set to all 0
○ Padding property set to all 5
○ Dock property set to Fill
Black area, a Panel having:
○ BackColor property set to Black
○ Margin property set to all 0
○ Padding property set to all 5
○ Dock property set to Fill
White label, a Label having:
○ BackColor property set to White
○ Margin property set to all 0
○ Padding property set to all 0
○ Dock property set to Fill
The structure of other cells are exactly the same, but the BackColor of Label and its parent (like the black one), to Transparent, so you see the BackColor of the most inner Panel (like the red one).
Note
The answer is completely based on setting Dock property to Fill and setting suitable Padding value for docked controls. But there is another elegant solution for keeping a control at center of a container automatically which is based on using a TableLayoutPanel having 1 row and 1 column instead of panel, and then setting Anchor property of child to None. This way the child will be centered horizontally and vertically in the TableLayoutPanel. You will find this post about it useful:
How to center a Label inside a Panel without setting Dock to Fill
So I actually reached a less complicated method. Instead of having a Panel within a Panel, I opted for keeping my original Panel, and creating a custom Label, which has an outside border whose thickness and color can be changed. This way I don't have to keep track of too many controls, and the CustomLabel displays everything needed.
Code for CustomLabel:
public class CustomLabel : Label
{
// Constructors
// Default Constructor
public CustomLabel() : base() { }
public CustomLabel(bool drawBorder, int borderThickness, Color borderColor, Color textColor) : base()
{
if (drawBorder)
{
BorderThickness = borderThickness;
BorderColor = borderColor;
}
Size = new Size(36, 36);
Text = "Info";
Anchor = (AnchorStyles.Left | AnchorStyles.Right);
AutoSize = false;
TextAlign = ContentAlignment.MiddleCenter;
Enabled = false;
Font = new Font("Microsoft Sans Serif", 6);
ForeColor = TextColor;
BorderStyle = BorderStyle.FixedSingle;
Dock = DockStyle.Fill;
}
// Creates a border of specified thickness and color
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (BorderStyle == BorderStyle.FixedSingle)
{
int halfThickness = BorderThickness / 2;
using (Pen p = new Pen(BorderColor, BorderThickness))
{
e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
halfThickness,
ClientSize.Width - BorderThickness, ClientSize.Height - BorderThickness));
}
}
}
public int BorderThickness { get; set; }
public Color BorderColor { get; set; }
}
Code for adding CustomLabel to Panels:
// Add Panels to TableLayoutPanel
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
// Create new Panel
Panel space = new Panel()
{
Size = new Size(45, 45),
Dock = DockStyle.Fill,
Margin = new Padding(0),
ForeColor = Color.Red
};
space.MouseClick += new MouseEventHandler(MouseDownOnSpace);
CustomLabel info = new CustomLabel(false, 0, Color.Empty, Color.Red); // Create new CustomLabel
space.Controls.Add(info); // Add CustomLabel to Panel
tlp.Controls.Add(space, j, i); // Add Panel to TableLayoutPanel
}
}
Code for adjusting the CustomLabel:
((CustomLabel)tlp.GetControlFromPosition(col, row).Controls[0]).BorderThickness = 6;
((CustomLabel)tlp.GetControlFromPosition(col, row).Controls[0]).BorderColor = Color.Yellow;
tlp.GetControlFromPosition(col, row).Controls[0].Text = tlp.GetControlFromPosition(col, row).Controls[0].Text; // Transfer space information
tlp.GetControlFromPosition(col, row).Refresh(); // Refresh Panel to show changes
This is the end result:
(As you can see, the ForeColor still doesn't change.)

C#: Rectangles drawn with DrawRectangle on a non-primary monitor doesn't render top and left borders

I have a full screen form and in the handler for the Paint event I am drawing a 2px border around the entire form. I create one of these forms for each screen attached to the computer. For some reason, the top and left borders are not drawing on any non-primary monitors. The form's background covers the entire screen but I can't see to draw (using GDI) on area about 3px down from the top and 3px in from the left of the screen.
My Paint event handler code is below.
private void OnPaint(object sender, PaintEventArgs e)
{
using (Graphics g = this.CreateGraphics())
{
int border = 2;
int startPos = 0;
// offset used to correctly paint all the way to the right and bottom edges
int offset = 1;
Rectangle rect = new Rectangle(startPos, startPos, this.Width - border + offset, this.Height - border + offset);
Pen pen = new Pen(Color.Red, border);
// draw a border
g.DrawRectangle(pen, rect);
}
}
Has anyone seen this before?
Your code works Correct.
You should know when you are using this.Width or this.Height, these values calculating with the frame that surround your form.
For the Height, the height of your form controls added to calculated height.
You can using this code :
using (Graphics g = this.CreateGraphics())
{
int border = 2;
int startPos = 0;
// offset used to correctly paint all the way to the right and bottom edges
int offset = 1;
Rectangle rect = new Rectangle(startPos, startPos, this.Width-20, this.Height-40);
Pen pen = new Pen(Color.Red, border);
// draw a border
g.DrawRectangle(pen, rect);
}
UPDATE :
If you want to calculating exact size you can use this code :
int width,height;
public Form1()
{
InitializeComponent();
PictureBox pc = new PictureBox();
pc.Dock = DockStyle.Fill;
this.Controls.Add(pc);
pc.Visible = false;
width = pc.Width;
height = pc.Height;
pc.Dispose();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = this.CreateGraphics())
{
int border = 2;
int startPos = 0;
// offset used to correctly paint all the way to the right and bottom edges
int offset = 1;
Rectangle rect = new Rectangle(startPos, startPos, width,height);
Pen pen = new Pen(Color.Red, border);
// draw a border
g.DrawRectangle(pen, rect);
}
}

Drawing ellipse in silverlight - incorrect placement

I've got this function that just draws an ellipse and places it on the given grid
public void drawEllipse(double top, double left, double height, double width, Grid grid)
{
Ellipse ellipse = new Ellipse();
ellipse.Height = height;
ellipse.Width = width;
SolidColorBrush brush = new SolidColorBrush();
brush.Color = Colors.Black;
ellipse.Stroke = brush;
ellipse.Fill = brush;
Canvas.SetTop(ellipse, top);
Canvas.SetLeft(ellipse, left);
grid.Children.Add(ellipse);
}
However, for some reason, it only wants to place the ellipse in the center of the grid, or (given fourth quadrant arguments) the fourth quadrant of the grid.
Am I doing something wrong?
You are adding your ellipse to a Grid control, but you're setting the Canvas.Top and Canvas.Left properties. Without the ellipse actually being on a Canvas, those two properties don't do anything. Either add a Canvas and use Canvas.Children.Add instead of Grid.Children.Add, or change your Canvas.SetTop and Canvas.SetLeft calls with calls to Grid.SetRow and Grid.SetColumn.

Windows Forms C# TabControl ImageList Alignment?

Is it possible to align the image icon from on a TabControl's ImageList to the right of the text?
Right now, the image icon gets put on the left, and the text is to the right of that. I would prefer the text to be on the left, and the icon to the right of that. Is this possible?
You can not do that unless you Draw the TabPage yourself. To do that you need to set the DrawMode property of the TabControl to OwnerDrawFixed and then handle the DrawItem Event.
This is a very simple example to do that, you can add some code to change the background color of the selected tab if you wish, to know which tab is selected just check the e.State value:
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
// values
TabControl tabCtrl = (TabControl)sender;
Brush fontBrush = Brushes.Black;
string title = tabCtrl.TabPages[e.Index].Text;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
int indent = 3;
Rectangle rect = new Rectangle(e.Bounds.X, e.Bounds.Y + indent, e.Bounds.Width, e.Bounds.Height - indent);
// draw title
e.Graphics.DrawString(title, tabCtrl.Font, fontBrush, rect, sf);
// draw image if available
if (tabCtrl.TabPages[e.Index].ImageIndex >= 0)
{
Image img = tabCtrl.ImageList.Images[tabCtrl.TabPages[e.Index].ImageIndex];
float _x = (rect.X + rect.Width) - img.Width - indent;
float _y = ((rect.Height - img.Height) / 2.0f) + rect.Y;
e.Graphics.DrawImage(img, _x, _y);
}
}

problem getting a form image background

I'm creating a datagridview transparent
//I got the parent background image
Bitmap parentBackGround = new Bitmap(this.Parent.BackgroundImage);
//Set the area i want to create equal to the size of my grid
Rectangle rect = new Rectangle(this.Location.X, this.Location.Y, this.Width, this.Height);
//And draw in the entire grid the area of the background image that is cover with my grid, making a "transparent" effect.
graphics.DrawImage(parentBackGround.Clone(rect, PixelFormat.Format32bppRgb), gridBounds);
When the backgroundimage of the grid's parent is show in an normal layout all work ok, but if the layout is stretch, center or any other, the transparency effent gone, have you any idea to fix it?
why not trying with the TransparencyKey property (Form) Instead?
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.transparencykey.aspx
Well i create a bitmap and copy the background image of the form parent of the grid in it exactly size, and then use only the part it cover my grid.
I inherit from grid and override those methods:
protected override void PaintBackground(Graphics graphics, Rectangle clipBounds, Rectangle gridBounds)
{
base.PaintBackground(graphics, clipBounds, gridBounds);
if (DesignMode) return;
Control tmpParent = Parent;
int locationX = this.Location.X;
int locationY = this.Location.Y;
while (tmpParent.BackgroundImage == null)
{
locationX += tmpParent.Location.X;
locationY += tmpParent.Location.Y;
tmpParent = tmpParent.Parent;
}
Rectangle rectSource = new Rectangle(locationX, locationY, this.Width, this.Height);
Rectangle rectDest = new Rectangle(0, 0, rectSource.Width, rectSource.Height);
Bitmap b = new Bitmap(tmpParent.ClientRectangle.Width, tmpParent.ClientRectangle.Height);
Graphics.FromImage(b).DrawImage(tmpParent.BackgroundImage, tmpParent.ClientRectangle);
graphics.DrawImage(b, rectDest, rectSource, GraphicsUnit.Pixel);
SetCellsTransparent();
}
public void SetCellsTransparent()
{
this.EnableHeadersVisualStyles = false;
this.ColumnHeadersDefaultCellStyle.BackColor = Color.Transparent;
this.RowHeadersDefaultCellStyle.BackColor = Color.Transparent;
foreach (DataGridViewColumn col in this.Columns)
{
col.DefaultCellStyle.BackColor = Color.Transparent;
col.DefaultCellStyle.SelectionBackColor = Color.Transparent;
}
}

Categories

Resources