After form on paint, children controls don't repaint themself - c#

I'm making a custom form with FormBorderStyle is none. In the form, I have a panel docked on the top of the form. The panel has some buttons docked on the right.
I overrided OnPaint for the form to draw a border for it, when I resize the form, buttons on the panel were still at their location. I tried to use form.Invalidate() but nothing happens.
I'm sorry but I'm not allowed to post picture here.
Here it the code of the form
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Rectangle borderRectangle = this.ClientRectangle;
borderRectangle.Inflate(-1, -1);
//ControlPaint.DrawBorder3D(e.Graphics, borderRectangle, Border3DStyle.RaisedOuter);
ControlPaint.DrawVisualStyleBorder(e.Graphics, borderRectangle);
}
protected override void OnResize(EventArgs e)
{
this.Invalidate(true);
}

Finally, I solved the problem by removing OnResize by OnClientSizeChanged :)
protected override void OnClientSizeChanged(EventArgs e)
{
this.Invalidate(true);
}

Related

Windows Forms unusual mouse manipulation

I have a Windows Form in which I'm rendering a map that I can zoom in and out of. I have it set so that if you hold the left mouse button, it pans across the map, and if you use the mouse wheel, it zooms in and out on the spot where the mouse cursor currently points. But some of my user base uses Mac hardware, and may not have a mouse with a wheel. I want to be able to hold the right mouse button and move the mouse forward and backward to zoom in and out, but to do this, I need to lock the cursor in place while the right mouse button is clicked. Any thoughts on how to do this?
I've tried Cursor.Position = Point(...) but that doesn't work immediately and causes some bizarre behavior.
I recommend you to Hide the cursor on MouseDown, then Show it in MouseUp. Till then you can draw the cursor manually if you want to show it.
private Point? downPoint;
protected override void OnMouseDown(MouseEventArgs e)
{
downPoint = this.PointToClient(MousePosition);
Cursor.Hide();
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (downPoint.HasValue)
{
Cursor.Show();
}
downPoint = null;
base.OnMouseUp(e);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (downPoint.HasValue)
{
Cursor.Draw(e.Graphics, new Rectangle(downPoint.Value, Cursor.Size));
}
}
I don't know why setting the Cursor.Position method doesn't work in your case. I have taken a simple windows form without placing any controls I have overided following methods and set the Cursor.Position property OnMouseMove method. Its working.
Just paste the following code in your form and run it.
Point p = Point.Empty;
protected override void OnMouseDown(MouseEventArgs e)
{
p = this.PointToScreen(e.Location);
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
p = Point.Empty;
base.OnMouseUp(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (p != Point.Empty)
Cursor.Position = p;
base.OnMouseMove(e);
}

PictureBox disappears after resize my Form

I have a MainForms.cs with Ribbon, I want to put a transparent PictureBox on the top right of the ribbon (The PictureBox represent my logo).
This is what I have tried:
I put the PictureBox on the top right of the Ribbon
I set BackColor to Transparent.
I load a PNG image (Containe transparence)
I set the parent of the image to be the ribbon (and like that the PictureBox will be transparent relative to Ribbon)
Code :
InitializeComponent();
pictureBox1.Parent = ribbon1;
Until here all is working great.
My Problem :
When I resize my Form, the PictureBox disappears.
On the OnPaint fonction i reset all setting like that :
protected override void OnPaint(PaintEventArgs pe)
{
this.Activate();
pictureBox1.Visible = true;
pictureBox1.Show();
pictureBox1.BringToFront();
}
But nothing makes the Picturebox appear. Please, can you tell me what i missed.
I downloaded the DLL that you are using and created a small test example. What I noticed is the Parent property of the PictureBox was set to null. By adding the Parent back to the Picturebox in the OnPaint event I was able to get it working if the size of the Form was growing, but would disappear when the Form size was reduced. When I put the same code in the OnResize EventHandler it works like you would expect.
public partial class Form1 : Form
{
PictureBox pictureBox1 = new PictureBox();
public Form1()
{
InitializeComponent();
pictureBox1.Image = Image.FromFile(#"C:\temp\test.jpg");
pictureBox1.Parent = ribbon1;
pictureBox1.Location = new Point(this.Width-pictureBox1.Width,10);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (pictureBox1.Parent == null)
{
pictureBox1.Parent = ribbon1;
pictureBox1.Visible = true;
pictureBox1.Location = new Point(this.Width - pictureBox1.Width, 10);
}
}
}

Override paint method doesn't work correctly

I am trying to draw a rectangle on PictureBox without using Paint event of picturebox,So i override the Onpaint method :
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = pictureBox1.CreateGraphics();
Pen bPen=new Pen(Color.Blue,3);
dc.DrawRectangle(bPen,0,0,50,50);
}
}
But the rectangle doesn't appear in first time ,but when i change the size of form using mouse my rectangle is appeared why ?!!!
I understand that you do not want to use the Paint event of the PictureBox. Your code wouldn't work since the form gets rendered before its containing elements.
I offer you a solution: draw on a bitmap and then insert that bitmap into the PictureBox through its Image public member.
private void loadDrawing(){
Bitmap map = new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
var graph = Graphics.FromImage(map);
graph.DrawRectangle(new Pen(Color.Blue, 3), 0, 0, 50, 50);
pictureBox1.Image = map;
}
Let's say you want to make the Rectangle to show up upon load:
private void Form1_Load(object sender, EventArgs e)
{
loadDrawing();
}
The problem is that you override OnPaint method of the form instead of Paint event of the PictureBox. Form's OnPaint happens, when the form needs repainting, and that's independent of what happens with the PictureBox.
Implement OnPaint event of the PictureBox and then you will not have to create Graphics object manually - simply use one provided in the event arguments.
private void Form1_Load(object sender, EventArgs e)
{
// No need to do that
// pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(10, 10, 20, 20));
}
Edit: (in response to comments)
If you want to update the paintbox periodically, do the following:
Keep the data required to draw the scene somewhere in the form, possibly as a private field
Use these data to draw the scene in Paint event of the PictureBox
When you need to update the scene, modify the data accordingly, and then call the Invalidate method of the PictureBox. It will cause the Paint event to fire and the scene will be redrawn.
Remember though, that all calls to UI methods from the threads has to be synchronized to the main UI thread (otherwise they won't work or cause problems).
You are overriding the paint method of the form, while you paint the PictureBox. That isn't how it is meant to be. The PictureBox will still do it's own rendering.
If you really want to do painting of the PictureBox, implement the Paint event of the PictureBox or create a custom control where you draw a rectangle, and a picture.
After you draw the form refresh the form using this :-
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = pictureBox1.CreateGraphics();
Pen bPen=new Pen(Color.Blue,3);
dc.DrawRectangle(bPen,0,0,50,50);
this.Refresh() ;
}

Add a scroll event to repaint form

I am new to C#, and I am experimenting by placing a dot where a user clicks on a form. I am working with a 300 x 200 form with a maximum size of 640 x 480. Using the form's AutoScrollMinSize property, I set this maximum size:
this.AutoScrollMinSize = new Size(640, 480);
I am able to place dots onto the form, but the dots disappear once I have scrolled out of the visible area. Since I created the scroll area manually, I am looking for a way to add a scroll event handler that will call this.Invalidate() to repaint the form whenever scrolling occurs. Any advice is greatly appreciated.
Here is what I have:
public Form1()
{
InitializeComponent();
this.AutoScrollMinSize = new Size(640, 480);
vScrollBar vScrollBar1 = new VScrollBar();
vScrollBar1.Scroll += new ScrollEventHandler(this.vScrollBar1_Scroll);
}
And here is how I'm calling the event handler:
private void vScrollBar1_Scroll(Object sender, ScrollEventArgs e)
{
this.Invalidate();
}
I got this example from the Microsoft documentation, but the drawing is still disappearing when I scroll vertically, so I know the form is not repainting.
You don't need that VScrollBar control (which you never added to the form anyway).
Just override the OnScroll method of the form:
protected override void OnScroll(ScrollEventArgs se) {
base.OnScroll(se);
this.Invalidate();
}
try to put your event in a deligate
and use
http://msdn.microsoft.com/en-us/library/system.windows.forms.splitter.aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.scrollbar.aspx
How to set scroll bar in Windows form
and set
vScrollBar.visible = true and if it is in pannel or form set AutoScroll = true

Updating TabControl.DisplayRectangle manually

I am writing a custom drawn TabControl class in C#.
My InitializeComponent method (which is called by the constructor) behaves like so, in order to custom draw the control:
private void InitializeComponent()
{
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.UpdateStyles();
this.DrawMode = TabDrawMode.OwnerDrawFixed;
}
The TabControl uses two rectangle surfaces;
The ClientRectangle which contains the entire control
The DisplayRectangle which is the portion of the control to display TabPage content
As I want to adjust the DisplayRectangle, I have overridden its property (which is get only):
public override Rectangle DisplayRectangle
{
get
{
return this.displayRectangle; // points to a local rectangle, rather than base.DisplayRectangle
}
}
Then I've overridden OnSizeChanged in order to update the display rectangle size:
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
this.displayRectangle = this.ClientRectangle;
this.displayRectangle.Y += this.ItemSize.Height + 4;
this.displayRectangle.Height -= this.ItemSize.Height + 4;
}
The problem I'm encountering is, when the TabControl is re-sized, the DisplayRectangle works and re-sizes accordingly, but when the parent form is maximized/minimized (thus changing the control size), the display rectangle does not update.
How should I go about fixing this? Are there any guidelines for managing the display rectangle manually?
I have discovered a couple of things which help to fix this issue. They are; to resize the display rectangle using an override of the OnResize method, and to set the bounds for each tab in the tab control when you have finished resizing the display rectangle...e.g:
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.displayRectangle = this.ClientRectangle;
this.displayRectangle.Y += this.ItemSize.Height + 4;
this.displayRectangle.Height -= this.ItemSize.Height + 4;
foreach(TabPage page in this.TabPages)
{
page.SetBounds(
this.DisplayRectangle.X,
this.DisplayRectangle.Y,
this.DisplayRectangle.Width,
this.DisplayRectangle.Height,
SpecifiedBounds.All
);
}
this.Refresh(); // Can optimize this!
}

Categories