Picturebox中的可移动FrameControl无法正常工作 [英] Movable FrameControl in Picturebox not working as intended
问题描述
我正在使用以下代码将可移动的Frame控件添加到图片框,并在帧的外部区域添加半透明的背景,但是黑色的半透明颜色并未按预期出现在帧的外部。
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
}
}
}
}
推荐答案
PicturBox
仅绘制需要重绘的控件部分。由于已经在图片框可见后在运行时添加了控件,因此您需要在添加 FrameControl
重新绘制整个控件后使图片框无效。
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.
在添加或删除 FrameControl
的父级时考虑调用 Invalidate
方法
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();
}
这篇关于Picturebox中的可移动FrameControl无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!