0

i am implementing the solution from Reza Aghaei from this post Creating Custom Picturebox with Draggable and Resizable Selection Window.

i am triggering the selection control from a menu button, the rectangle selection works fine, but i don't know how trigger the part where he add the "fancy effect of filling outside of the frame with semi-transparent color", i want this happend after i pressing the button to load the resizable control.

the code of that part is this:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.ExcludeClip(pictureBox1.Controls[0].Bounds);
    using (var b = new SolidBrush(Color.FromArgb(100, Color.Black)))
        e.Graphics.FillRectangle(b, pictureBox1.ClientRectangle);
}

and this is my function to load the custom control

private void selectToolStart(object sender, EventArgs e)
{
    var s = 100;
    var c = new FrameControl();
    c.Size = new Size(s, s);
    c.Location = new Point((pictureBox1.Width - s) / 2, (pictureBox1.Height - s) / 2);
    pictureBox1.Controls.Add(c);
}

Any advice is welcome. Thanks in advance

UPDATE:

After all the help from you guys, i came with this code:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (pictureBox1.HasChildren == true)
    {
        e.Graphics.ExcludeClip(pictureBox1.Controls[0].Bounds);
        using (var b = new SolidBrush(Color.FromArgb(100, Color.Black)))
        e.Graphics.FillRectangle(b, pictureBox1.ClientRectangle);
    }
    pictureBox1.Invalidate();
}

UPDATE 2

Taking the advice from TaW i move the invalidate from paint event to selectToolStart() function. so this time the code stay as follow

private void selectToolStart(object sender, EventArgs e)
{
    var s = 100;
    var c = new FrameControl();
    c.Size = new Size(s, s);
    c.Location = new Point((pictureBox1.Width - s) / 2, (pictureBox1.Height - s) / 2);
    pictureBox1.Controls.Add(c);
    pictureBox1.Invalidate();
}

and the Paint event stay as follow

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (pictureBox1.HasChildren == true)
    {
        e.Graphics.ExcludeClip(pictureBox1.Controls[0].Bounds);
        using (var b = new SolidBrush(Color.FromArgb(100, Color.Black)))
        {
            e.Graphics.FillRectangle(b, pictureBox1.ClientRectangle);
        }
    }
}

It seems it get the job done. any feedback or suggestion please. Thanks all you guys.

Mben
  • 19
  • 1
  • 5
  • 1
    You can't. What you should do is to put an pictureBox1.Invalidate call in the click event to trigger the paint event. You can't call it directly! – TaW May 11 '21 at 06:36
  • Does this answer your question? [How to refresh PictureBox](https://stackoverflow.com/questions/9030622/how-to-refresh-picturebox) –  May 11 '21 at 06:53
  • Use `private void Control_Click(...) { pictureBox/*(sender as PictureBox)*/.`[`Refresh`](https://learn.microsoft.com/dotnet/api/system.windows.forms.control.refresh)`(); }`. Else there is [Control.InvokePaint](https://learn.microsoft.com/dotnet/api/system.windows.forms.control.invokepaint). –  May 11 '21 at 07:00
  • thanks, i am still lost, i dont get it very well, so i have to take this code: e.Graphics.ExcludeClip(pictureBox1.Controls[0].Bounds); using (var b = new SolidBrush(Color.FromArgb(100, Color.Black))) e.Graphics.FillRectangle(b, pictureBox1.ClientRectangle); to another function? and then what? – Mben May 11 '21 at 07:26
  • 1
    @Mben Why do you want to put this OnPaint code elsewhere? Refresh or InvokePaint should call it, thus let that here, isn't it? –  May 11 '21 at 07:33
  • i just need, the fill color of the paint event show and works only when the control select tool is enabled. because not all the time my picturebox will display the custom control. i dont know how the paint event works, because is keeping update every time i move the control selection tool. – Mben May 11 '21 at 07:49
  • _so i have to take this code:... to another function?_ No, nobody suggested that. All drawing should happen in the Paint event. To trigger it, esp. when data have changed call pbox.Invalidate(). So you may well have to add logic to the Paint event to decide just what to paing with the given states of your app.. – TaW May 11 '21 at 07:50
  • i just came with a solution, i update my question, please if somebody can give me feedback. – Mben May 11 '21 at 08:12
  • @Mben "*fill color of the paint event show and works only when the control select tool is enabled*". Thus you can use a conditional variable as instance bool var like `SelectionToolEnabled`, that is true when the selection action starts, and false when finished. And use this flag to do a special paint action when true like drawing a red emty bordered shape according to the type of selection with a dotted brush. –  May 11 '21 at 08:20
  • 2
    No, no, no! Never put an control.Invalidate in the control.Paint event as this would cause an endless loop. Invalidate when the data change, maybe in your click event! – TaW May 11 '21 at 08:37
  • @TaW i change the code and update my post, thanks by your advice, you are right, maybe i am not expert but as far i see how this paint method works , is some kind of loop who keep going listening the picturebox. or i am wrong? – Mben May 11 '21 at 09:04

0 Answers0