Movable FrameControl in Picturebox not working as intended

牧云@^-^@ 提交于 2020-01-04 09:08:33

问题


I'm using the following code to add a movable Frame control to a picturebox and add a translucent background to the outer area of the frame.But the black translucent color is not appearing outside the frame as intended.It is supposed to fill up all the area outside the frame.On dragging the frame its producing the black area where its dragged.

I'm using a picturebox with size mode set to Zoom.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DXApplication5
{
    public partial class Form1 : DevExpress.XtraEditors.XtraForm
    {
        public Form1()
        {
            InitializeComponent();
            pictureBox1.Paint += PictureBox1_Paint;
        }

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

        private void button1_Click(object sender, EventArgs e)
        {
            var s = 300;
            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);
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }

    public class FrameControl : Control
    {
        public FrameControl()
        {
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            DoubleBuffered = true;
            ResizeRedraw = true;
            BackColor = Color.Transparent;
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var p = new Pen(Color.Black, 4))
            {
                p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                e.Graphics.DrawRectangle(p, 0, 0, Width - 1, Height - 1);
            }
        }
        const int WM_NCHITTEST = 0x84;
        const int WM_SETCURSOR = 0x20;
        const int WM_NCLBUTTONDBLCLK = 0xA3;
        protected override void WndProc(ref Message m)
        {
            int borderWidth = 10;
            if (m.Msg == WM_SETCURSOR)  /*Setting cursor to SizeAll*/
            {
                if ((m.LParam.ToInt32() & 0xffff) == 0x2 /*Move*/)
                {
                    Cursor.Current = Cursors.SizeAll;
                    m.Result = (IntPtr)1;
                    return;
                }
            }
            if ((m.Msg == WM_NCLBUTTONDBLCLK)) /*Disable Mazimiz on Double click*/
            {
                m.Result = (IntPtr)1;
                return;
            }
            base.WndProc(ref m);
            if (m.Msg == WM_NCHITTEST)
            {
                var pos = PointToClient(new Point(m.LParam.ToInt32() & 0xffff,
                    m.LParam.ToInt32() >> 16));
                if (pos.X <= ClientRectangle.Left + borderWidth &&
                    pos.Y <= ClientRectangle.Top + borderWidth)
                    m.Result = new IntPtr(13); //TOPLEFT
                else if (pos.X >= ClientRectangle.Right - borderWidth &&
                    pos.Y <= ClientRectangle.Top + borderWidth)
                    m.Result = new IntPtr(14); //TOPRIGHT
                else if (pos.X <= ClientRectangle.Left + borderWidth &&
                    pos.Y >= ClientRectangle.Bottom - borderWidth)
                    m.Result = new IntPtr(16); //BOTTOMLEFT
                else if (pos.X >= ClientRectangle.Right - borderWidth &&
                    pos.Y >= ClientRectangle.Bottom - borderWidth)
                    m.Result = new IntPtr(17); //BOTTOMRIGHT
                else if (pos.X <= ClientRectangle.Left + borderWidth)
                    m.Result = new IntPtr(10); //LEFT
                else if (pos.Y <= ClientRectangle.Top + borderWidth)
                    m.Result = new IntPtr(12); //TOP
                else if (pos.X >= ClientRectangle.Right - borderWidth)
                    m.Result = new IntPtr(11); //RIGHT
                else if (pos.Y >= ClientRectangle.Bottom - borderWidth)
                    m.Result = new IntPtr(15); //Bottom
                else
                    m.Result = new IntPtr(2); //Move
            }
        }
    }
}

回答1:


PicturBox just paints those part of the control which need repaint. Since have added the control at run-time after the picture box get visible, you need to invalidate picture box after adding FrameControl to repaint the entire control.

Consider calling Invalidate method of the parent of FrameControl when you add or remove it from the parent or when you change visibility of the control.

private void button1_Click(object sender, EventArgs e)
{
    var s = 300;
    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);
    c.VisibleChanged
    pictureBox1.Invalidate();
}


来源:https://stackoverflow.com/questions/55074941/movable-framecontrol-in-picturebox-not-working-as-intended

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!