我正在使用以下代码向图片框添加可移动的Frame控件,并在框的外部区域添加半透明的背景,但是黑色的半透明颜色并未按预期的那样出现在框的外部,应该会填满所有拖动框架时会在其拖动的区域产生黑色区域。

我使用的图片框的尺寸模式设置为“缩放”。
c# - Picturebox中的可移动FrameControl无法正常工作-LMLPHP

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
            }
        }
    }
}

最佳答案

PicturBox仅绘制需要重绘的控件部分。由于已在图片框可见后在运行时添加了控件,因此在添加FrameControl重新绘制整个控件后,您需要使图片框无效。

当您从父级添加Invalidate方法或从父级中删除它时,或者更改控件的可见性时,请考虑调用FrameControl父级的方法。

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();
}

关于c# - Picturebox中的可移动FrameControl无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55074941/

10-11 00:59