Movable FrameControl в Picturebox не работает, как задумано - PullRequest
2 голосов
/ 09 марта 2019

Я использую следующий код, чтобы добавить подвижный элемент управления Frame в Picturebox и добавить полупрозрачный фон во внешнюю область рамки. Но черный полупрозрачный цвет не появляется вне рамки, как предполагалось. Предполагается, чтоЗаполните всю область за пределами рамки. При перетаскивании рамки создается черная область, куда ее перетаскивают.

Я использую графический блок с режимом размера, установленным на Увеличение .enter image description here

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 Ответ

1 голос
/ 10 марта 2019

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