c# - Picturebox 中的 Movable FrameControl 未按预期工作
问题描述
我正在使用以下代码将可移动的框架控件添加到图片框,并在框架的外部区域添加半透明背景。但是黑色半透明颜色没有按预期出现在框架之外。它应该填满所有框架外的区域。在拖动框架时,它会产生拖动的黑色区域。
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();
}
推荐阅读
- php - Angularjs 表单操作并返回错误
- symfony4 - 无效的 YAML Symfony4
- java - 使用 Java (netbeans) 连接到远程 SQL 服务器时出现 SSL 错误
- javascript - 带有 html 代码和打印方法的对象
- c# - 不能简单地遍历列表以匹配密码(c#winform)
- ios - 使用 dataTask 的 NSURLCaching 无法在离线时使用 NSURLRequest 读取缓存
- python - 熊猫数据框子集
- python - 如何确定递归中的最后一个堆栈空间
- java - Flutter:我在 Flutter 中遇到了一个问题。我认为问题在于不动态适应的卡
- peewee - 如何在 peewee 中即时将 CharField 转换为 DateTimeField?