I added a label control to form1 designer and assign some text to it.
Then i did label mouse click event:
private void label5_MouseClick(object sender, MouseEventArgs e)
{
DrawRectangleOnLabel = true;
label5.Invalidate();
}
And the label paint event:
private void label5_Paint(object sender, PaintEventArgs e)
{
if (DrawRectangleOnLabel == true)
{
e.Graphics.DrawRectangle(Pens.Red, 0, 0, label5.Width, label5.Height);
}
}
But what i see when i click on the label is half rectangle only the Left and Top the right and bottom of the rectangle not exist/show.
This is because the rectangle is drawn with a pen width of 1 and the right and bottom portions fall outside the bounds of the label. Just make it one pixel smaller :
e.Graphics.DrawRectangle(Pens.Red, 0, 0, label1.Width - 1, label1.Height - 1);
Alternatively, you can use the ControlPaint method instead :
ControlPaint.DrawBorder(e.Graphics, label1.DisplayRectangle,
Color.Red, ButtonBorderStyle.Solid);
This gives you access to various other ButtonBorderStyles (dashed, dotted, inset, outset).
Why don't you try BorderStyle property on MouseClick event. And assign single event for all labels.
label1.MouseClick += new EventHandler(this.AllLable_MouseClick);
label2.MouseClick += new EventHandler(this.AllLable_MouseClick);
label3.MouseClick += new EventHandler(this.AllLable_MouseClick);
private void AllLable_MouseClick(object sender, MouseEventArgs e)
{
Label lbl = (Label)sender;
if (lbl.BorderStyle == BorderStyle.FixedSingle)
lbl.BorderStyle = BorderStyle.None
else
lbl.BorderStyle = BorderStyle.FixedSingle
}
For a simple "box" just add a Forms.Panel and place your controls on it. Then set the Panel border to FixedSingle.
Related
I am making a border around a picture box by simply drawing a rectangle around it. However since there is a panel behind the picturebox, I cannot see the border around the picturebox (despite the fact that I have drawn the border around the picture. Here's the code:
private void Form1_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Maximized;
Graphics objGraphics = null;
objGraphics = this.CreateGraphics();
objGraphics.Clear(SystemColors.Control);
objGraphics.DrawRectangle(Pens.Blue,
ileriresmi.Left - 1, ileriresmi.Top - 1,
ileriresmi.Width + 1, ileriresmi.Height + 1);
objGraphics.Dispose();
}
you may try this..but it will draw inside the picture box
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(new Pen(Color.Red, 2f),0,0,pictureBox1.Size.Width-2, pictureBox1.Size.Height-2);
}
Complete solution will be like this.
add this class into your application and build application.
public class PicExt : PictureBox
{
private Color _borderColor;
private int _borderWidth;
[Browsable(true)]
public Color BorderColor {
get { return _borderColor; }
set { _borderColor = value; this.Invalidate(); }
}
[Browsable(true)]
public int BorderWidth {
get { return _borderWidth; }
set { _borderWidth = value; this.Invalidate(); }
}
public PicExt()
{
_borderColor = Color.Red;
_borderWidth = 3;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
pe.Graphics.DrawRectangle(new Pen(BorderColor, BorderWidth), BorderWidth, BorderWidth, this.Size.Width - (BorderWidth*2), this.Size.Height - (BorderWidth*2));
}
}
after building application you will see new control "PicExt" in your toolbox.
replace pictureBox with PicExt Control
and subscribe the click event like this.
private void button1_Click(object sender, EventArgs e)
{
//set the color here
picExt1.BorderColor = Color.Red;
//and frame width
picExt1.BorderWidth = 5;
}
it should work like exactly you want.
There are a couple things wrong here. First, you're doing your drawing on the form, which is covered by the panel you mention, and second, you're only drawing the border once, in the Load event, rather than every time the form receives a WM_PAINT message.
See here for an explanation of why the latter is wrong.
As for getting the border drawn in the right place, why not just set the BackColor of the panel that holds the PictureBox to Color.Blue and give that panel a nonzero value for Padding? (Or, if the panel contains other controls, add an intermediate panel just for the border.)
I have one Panel and when I click on add Button I add one Control under other added controls. When I click on another Button I remove Control which was added as last.
This works fine. On that panel I have AutoScroll setting set to True and when I add more controls it properly appears and I can use it. When I remove some controls Panel properly hides ScrollBar ONLY if the "animation" on that ScrollBar doesn't run at that time.
If no animation is running on that ScrollBar it disapears properly - doesn't matter if you have mouse over it or not.
If you have mouse over the ScrollBar and quickly move over the remove Button and click before ScrollBars animation is finished the Control is removed, but the inactive ScrollBar is still there. In Buttons click handler I tried to call Invalidate, Update and Refresh methods over the Panel but nothing works.
I tested this only on Windows 7.
If you don't know what I mean please try to look at this short video (20s without sound): http://youtu.be/-0EfRXrGbuc
You forgot to post mcve. So here is one (add panel and two buttons):
private void button1_Click(object sender, EventArgs e)
{
panel1.Controls.Add(new Button() { Top = panel1.Controls.Count * 30 });
}
private void button2_Click(object sender, EventArgs e)
{
if (panel1.Controls.Count > 0)
panel1.Controls.RemoveAt(panel1.Controls.Count - 1);
panel1.Refresh();
}
I am able to reproduce the problem
it's winforms, baby (c).
Possible workaround is to call Refresh() by using e.g. Timer or some of mouse events (it will not prevent issue, but use will easily fix it by e.g. moving mouse inside panel1) or you can postpone the possibility of deleting buttons itself for a short time after panel1.MouseLeave. All this kind of workarounds.
I hoped that there is some better way, but now I don't see any, so based on answer from Sinatr I decided to use Timer and cobined it with checking pixel Color to determine if the ScrollBar is still visible.
private Timer _timer = new Timer {Interval = 500};
public Form1()
{
InitializeComponent();
_timer.Tick += TimerOnTick;
}
private void button2_Click(object sender, EventArgs e)
{
if (panel1.Controls.Count > 0)
{
var wasVisible = panel1.VerticalScroll.Visible;
panel1.Controls.RemoveAt(panel1.Controls.Count - 1);
buttons.RemoveAt(buttons.Count - 1);
if (wasVisible != panel1.VerticalScroll.Visible)
{
_timer.Start();
}
}
}
private bool IsBackgroundColor()
{
var point = panel1.Location;
point.Offset(panel1.Width - 9, panel1.Height - 11);
point = PointToScreen(point);
Image imgScreen = new Bitmap(1, 1);
using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
using (Graphics g = Graphics.FromImage(bmp))
using (Graphics gr = Graphics.FromImage(imgScreen))
{
g.CopyFromScreen(point, new Point(0, 0), new Size(1, 1));
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
gr.DrawImage(bmp, new Rectangle(0, 0, 1, 1));
var color = bmp.GetPixel(0, 0);
return color.R == panel1.BackColor.R && color.G == panel1.BackColor.G && color.B == panel1.BackColor.B;
}
}
private void TimerOnTick(object sender, EventArgs eventArgs)
{
if (!IsBackgroundColor() && !panel1.VerticalScroll.Visible)
{
panel1.Refresh();
}
else
{
_timer.Stop();
}
}
I was not able to use Panel.DrawToBitmap because it doesn't draw ScrollBars. I also start the Timer only when the ScrollBar was visible and now it shouldn't be.
It is important to mention that the pixel Color checking is possible only if you know the Color which should be there if the ScrollBar is hidden. It is not necessary have to be Panel.BackColor.
I'm using C# for developing a simple tool that has a picturebox inside a panel. The panel has property Autoscroll = true. If the Image of that picturebox is larger than the panel the panel has scrollbars
I could draw a rectangle on paint event of picturebox. But when i scroll, this rectangle disappears. I know it need to repaint it after moving the scrollbar but i don't know how to restore it again.
x, y, width, heigth, zoom is global variable and when use click in to treenode, it'll have data.
private void pictureBoxView_Paint(object sender, PaintEventArgs e)
{
if (choose == true)
{
Size newSize = new Size((int)(pictureBoxView.Image.Width * zoom),
(int)(pictureBoxView.Image.Height * zoom));
Graphics graphic = pictureBoxView.CreateGraphics();
Pen pen = new Pen(Color.Red, 3);
graphic.DrawRectangle(pen, x, y, width, height);
pen.Dispose();
}
}
private void treeViewTemplate_AfterSelect(object sender, TreeViewEventArgs e)
{
// refresh picturebox
pictureBoxView.Refresh();
// allow repaint
choose = true;
string[] value = treeViewTemplate.SelectedNode.Tag.ToString().Split(',');
x = Int32.Parse(value[0]);
y = Int32.Parse(value[1]);
width = Int32.Parse(value[2]);
height = Int32.Parse(value[3]);
zoom = Double.Parse(value[4]);
//MessageBox.Show("x = " + y + ", y = " + y + ", width = " + width + ", height = " + height + ", zoom = " + zoom);
// This call draw a rectangle again when I choose a value from TreeNode's Tag
pictureBoxView_Paint(this, null);
}
you also can use pictureBoxView.Refresh()
and define two local variable save the scroll offset through ScrollEventArgs.NewValue
if you do not want to paint when scrolling, you can use this
private void panel1_Paint(object sender, PaintEventArgs e)
{ pictureBox1.Refresh();}
In general you should use Invalidate method in order to redraw a surface of the control:
pictureBoxView.Invalidate();
Here is a sample of redrawing a PictureBox that is inside a Panel:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
var rectangle = new Rectangle(10, 10, 100, 100);
e.Graphics.DrawRectangle(Pens.Red, rectangle);
}
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
pictureBox1.Invalidate();
}
The fixed red rectangle is redrawed when panel is scrolled.
In this case (PictureBox in Panel control), you must create a method, which drawing on teh picture box. And you puts the drawing method in the Panel ScrollEvent.
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
Drawing();
}
I'm very new in C#
I want a rectangle to appear wherever there's a mouseclick on a panel
Here's my code:
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
int x = e.Location.X;
int y = e.Location.Y;
if (radioButton1.Checked == false)
{
((Panel)sender).Invalidate(new Rectangle(x * 40, y * 40, 40, 40));
}
else if (radioButton2.Checked == true)
{
return;
}
}
I wonder how to change the color of the rectangle?
Please advise me if my code is wrong.
Thanks.
Your drawing should be performed in the panel's Paint event handler. When you click the panel, create the rectangle (in the MouseUp event of the panel) and store it in a collection of rectangles (such as a dictionary). Then refresh the panel. In the panel's Paint event, draw all the rectangles. Here is a simple example:
Dictionary<Color, List<Rectangle>> rectangles = new Dictionary<Color, List<Rectangle>>();
private void panel1_Paint(object sender, PaintEventArgs e)
{
//The key value for the dictionary is the color to use to paint with, so loop through all the keys (colors)
foreach (var rectKey in rectangles.Keys)
{
using (var pen = new Pen(rectKey)) //Create the pen used to draw the rectangle (using statement makes sure the pen is disposed)
{
//Draws all rectangles for the current color
//Note that we're using the Graphics object that is passed into the event handler.
e.Graphics.DrawRectangles(pen, rectangles[rectKey].ToArray());
}
}
}
//This method just adds the rectangle to the collection.
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Color c = getSelectedColor(); //Gets a color for which to draw the rectangle
//Adds the rectangle using the color as the key for the dictionary
if (!rectangles.ContainsKey(c))
{
rectangles.Add(c, new List<Rectangle>());
}
rectangles[c].Add(new Rectangle(e.Location.X - 12, e.Location.Y - 12, 25, 25)); //Adds the rectangle to the collection
}
//Make the panel repaint itself.
panel1.Refresh();
}
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
Graphics g = panel1.CreateGraphics();
g.DrawRectangle(new Pen(Brushes.Black),
new Rectangle(new Point(e.X, e.Y), new
Size(100, 100)));
}
you can change the color in Brushes.Black part of code, change it as you desire
I want to draw a rectangle. Thing what I want is that show the user to rectangle on the mouse event.
Like in the image. This is for C# .net Forms application.
Help me to achieve this. Any help is appreciated.
Thank You
Yohan
You can do that in three steps:
First check if mouse is pressed down
If it is then on mouse move event keep initializing the rectangle with new positions while mouse is being dragged
Then on paint event draw the rectangle. (It will be raised for almost every mouse event, depends mouse refresh rate and dpi)
You can do somthing like this (in your Form):
public class Form1
{
Rectangle mRect;
public Form1()
{
InitializeComponents();
//Improves prformance and reduces flickering
this.DoubleBuffered = true;
}
//Initiate rectangle with mouse down event
protected override void OnMouseDown(MouseEventArgs e)
{
mRect = new Rectangle(e.X, e.Y, 0, 0);
this.Invalidate();
}
//check if mouse is down and being draged, then draw rectangle
protected override void OnMouseMove(MouseEventArgs e)
{
if( e.Button == MouseButtons.Left)
{
mRect = new Rectangle(mRect.Left, mRect.Top, e.X - mRect.Left, e.Y - mRect.Top);
this.Invalidate();
}
}
//draw the rectangle on paint event
protected override void OnPaint(PaintEventArgs e)
{
//Draw a rectangle with 2pixel wide line
using(Pen pen = new Pen(Color.Red, 2))
{
e.Graphics.DrawRectangle(pen, mRect);
}
}
}
later if you want to check if Buttons (shown in diagram) are in rectangle or not , you can do that by checking the Button's region and check if they lie in your drawn rectangle.
The solution by Shekhar_Pro draws a rectangle just in one direction (top to bottom, left to right) if you want to draw a rectangle regardless of the mouse position and the direction of the movement the solution is:
Point selPoint;
Rectangle mRect;
void OnMouseDown(object sender, MouseEventArgs e)
{
selPoint = e.Location;
// add it to AutoScrollPosition if your control is scrollable
}
void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point p = e.Location;
int x = Math.Min(selPoint.X, p.X)
int y = Math.Min(selPoint.Y, p.Y)
int w = Math.Abs(p.X - selPoint.X);
int h = Math.Abs(p.Y - selPoint.Y);
mRect = new Rectangle(x, y, w, h);
this.Invalidate();
}
}
void OnPaint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Blue, mRect);
}
Those blue rectangles look a lot like controls. Drawing a line on top of a control is hard to do in Winforms. You have to create a transparent window that overlays the design surface and draw the rectangle on that window. This is also the way the Winforms designer works. Sample code is here.