C#基础系列:开发自己的窗体设计器(实现控件的选择)
2013-01-11 17:16
1101 查看
【转 /article/1778181.html】
所谓控件的选择,就是在设计器上某个控件被选中或者控件获得焦点(通过Tab调整控件焦点)的时候,在控件的四周显示出调整手柄。
如下图:
如上,通过控件的调整手柄,我们可以调整控件的宽度和高度。而实现这个调整手柄的关键点其实得益于vs2005控件的灵活性。因为这8个正方形的调整手柄其实就是8个控件。
所以我们本文的重点如下:
1、开发自定义的调整手柄控件,也就是这正方形控件;
2、组合这8个调整手柄控件,目标是使设计器上的控件与调整手柄完全解耦,调整手柄能够不做任何的修改就可以应用于所有的控件;
3、设计器上的控件与调整手柄的对应方法,也就是选择控件的时候,能够在控件周围显示调整手柄。
下面我们针对这3个重点,在前一篇《在容器上拖动鼠标增加控件》的基础上,实现控件的选择功能。
1、开发自定义的调整手柄控件:
这其实属于自定义控件开发的问题,你首先增加“用户控件”,把控件名命名为UISizeDot,把下面的代码直接拷贝进去就可以了,所以我不做过多的描述,这里直接把代码贴出来好了。
[ToolboxItem(false)]
public partial class UISizeDot : Control
{
private bool _movable;
private Pen pen = new Pen(Color.Black);
public UISizeDot()
{
InitializeComponent();
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.TabStop = false;
this._movable = true;
}
/// <summary>
/// UISizeDot的边框颜色
/// </summary>
public Color BorderColor
{
get { return pen.Color; }
set
{
this.pen = new Pen(value);
this.Refresh();
}
}
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: 在此处添加自定义绘制代码
//this.BackColor = Color.White;
pe.Graphics.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
// 调用基类 OnPaint
base.OnPaint(pe);
}
public bool Movable
{
get { return this._movable; }
set { this._movable = value; }
}
}
2、组合这8个自定义调整手柄控件:
这个功能的目的就是,就是将这8个调整手柄控件组合起来,为了描述以及开发上的方便,我们使用一个控件数组UISizeDot[]_UISizeDot = new UISizeDot(8),我们约定从左上角按照顺时针方向到又下角分别_UISizeDot[0]~ _UISizeDot[7],其它的不用说了,看代码吧:
public enum ENUM_UISizeMode
{
FixNone = 0, //不固定
FixLocation = 1, //固定左上角,这时只能改变两边
FixHeight = 2, //固定高
FixWidth = 3, //固定宽
FixBoth = 4 //长宽都固定
}
public class UISizeKnob
{
private const int DOT_WIDTH = 7; //UISizeDot宽度
private const int DOT_HEIGHT = 7; //UISizeDot高度
private const int DOT_SPACE = 0; //UISizeDot与_Owner的距离
private const int DOT_COUNT = 8; //要显示的UISizeDot数
private System.Windows.Forms.Control _Owner;
private UISizeDot[] _UISizeDot;
private int _OldTop;
private int _OldLeft;
private int _NewTop;
private int _NewLeft;
private int _OldWidth;
private int _OldHeight;
private int _ClickAtX;
private int _ClickAtY;
private ENUM_UISizeMode _UISizeMode;
private bool _BeginDrag;
private Rectangle _OldRect;
private Color _DotColor = Color.White; //UISizeDot默认颜色为白色
private Color _DotBorderColor = Color.Black; //UISizeDot默认边框颜色为黑色
public event System.Windows.Forms.MouseEventHandler MouseDown = null;
public event System.Windows.Forms.MouseEventHandler MouseMove = null;
public event System.Windows.Forms.MouseEventHandler MouseUp = null;
private int j=0;
private bool _IsShow = false;
public UISizeKnob(System.Windows.Forms.Control owner)
{
this._Owner = owner;
this._NewTop = owner.Top;
this._NewLeft = owner.Left;
this._OldWidth = owner.Width;
this._OldHeight = owner.Height;
InitUISizeDots();
}
public bool IsShow
{
get { return this._IsShow; }
}
public Color DotColor
{
get { return this._DotColor; }
set
{
this._DotColor = value;
this._DotBorderColor = Color.FromArgb(Math.Abs(Convert.ToInt32(value.R) - 255), Math.Abs(Convert.ToInt32(value.G) - 255), Math.Abs(Convert.ToInt32(value.B) - 255));
}
}
/// <summary>
/// 注销
/// </summary>
public void Dispose()
{
for (int i = 0; i < this._UISizeDot.Length; i++)
{
this._UISizeDot[i].Dispose();
}
}
/// <summary>
/// this._Owner的大小改变模式
/// </summary>
public ENUM_UISizeMode UISizeMode
{
get { return this._UISizeMode; }
set { this._UISizeMode = value; }
}
private void InitUISizeDots()
{
this._UISizeDot = new UISizeDot[DOT_COUNT];
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i] = new UISizeDot();
this._UISizeDot[i].Width = DOT_WIDTH;
this._UISizeDot[i].Height = DOT_HEIGHT;
this._UISizeDot[i].Visible = false;
this._Owner.Parent.Controls.Add(this._UISizeDot[i]);
this._UISizeDot[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.UISizeDot_MouseDown);
this._UISizeDot[i].MouseMove += new System.Windows.Forms.MouseEventHandler(this.UISizeDot_MouseMove);
this._UISizeDot[i].MouseUp += new System.Windows.Forms.MouseEventHandler(this.UISizeDot_MouseUp);
}
this._UISizeDot[0].Cursor = System.Windows.Forms.Cursors.SizeNWSE;
this._UISizeDot[1].Cursor = System.Windows.Forms.Cursors.SizeNS;
this._UISizeDot[2].Cursor = System.Windows.Forms.Cursors.SizeNESW;
this._UISizeDot[3].Cursor = System.Windows.Forms.Cursors.SizeWE;
this._UISizeDot[4].Cursor = System.Windows.Forms.Cursors.SizeNWSE;
this._UISizeDot[5].Cursor = System.Windows.Forms.Cursors.SizeNS;
this._UISizeDot[6].Cursor = System.Windows.Forms.Cursors.SizeNESW;
this._UISizeDot[7].Cursor = System.Windows.Forms.Cursors.SizeWE;
SetUISizeDotsPosition();
}
public void ShowUISizeDots(bool show)
{
this._IsShow = show;
//2006-10-05:将此函数中所有的this._UISizeDot.Length全部替换成8
if (show)
{
SetUISizeDotsPositionByMove(false);
}
else
{
this._Owner.Parent.SuspendLayout();
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].Visible = show;
}
this._Owner.Parent.ResumeLayout();
return;
}
if (this._UISizeMode == ENUM_UISizeMode.FixNone)
{
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].BorderColor = this._DotBorderColor;
this._UISizeDot[i].BackColor = this._DotColor;
this._UISizeDot[i].Visible = show;
}
}
else if (this._UISizeMode == ENUM_UISizeMode.FixLocation)
{
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].BorderColor = this._DotBorderColor;
this._UISizeDot[i].BackColor = this._DotColor;
this._UISizeDot[i].Visible = show;
}
this._UISizeDot[0].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[0].Movable = false;
this._UISizeDot[1].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[1].Movable = false;
this._UISizeDot[2].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[2].Movable = false;
this._UISizeDot[6].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[6].Movable = false;
this._UISizeDot[7].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[7].Movable = false;
}
else if (this._UISizeMode == ENUM_UISizeMode.FixHeight)
{
this._UISizeDot[0].Visible = false;
this._UISizeDot[1].Visible = false;
this._UISizeDot[2].Visible = false;
this._UISizeDot[3].BorderColor = this._DotBorderColor;
this._UISizeDot[3].BackColor = this._DotColor;
this._UISizeDot[3].Refresh();
this._UISizeDot[3].Visible = show;
this._UISizeDot[4].Visible = false;
this._UISizeDot[5].Visible = false;
this._UISizeDot[6].Visible = false;
this._UISizeDot[7].BorderColor = this._DotBorderColor;
this._UISizeDot[7].BackColor = this._DotColor;
this._UISizeDot[7].Refresh();
this._UISizeDot[7].Visible = show;
}
else if (this._UISizeMode == ENUM_UISizeMode.FixWidth)
{
this._UISizeDot[0].Visible = false;
this._UISizeDot[1].BorderColor = this._DotBorderColor;
this._UISizeDot[1].BackColor = this._DotColor;
this._UISizeDot[1].Visible = show;
this._UISizeDot[1].Refresh();
this._UISizeDot[2].Visible = false;
this._UISizeDot[3].Visible = false;
this._UISizeDot[4].Visible = false;
this._UISizeDot[5].BorderColor = this._DotBorderColor;
this._UISizeDot[5].BackColor = this._DotColor;
this._UISizeDot[5].Visible = show;
this._UISizeDot[5].Refresh();
this._UISizeDot[6].Visible = false;
this._UISizeDot[7].Visible = false;
}
else if (this._UISizeMode == ENUM_UISizeMode.FixBoth)
{
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].BorderColor = this._DotBorderColor;
this._UISizeDot[i].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[i].Movable = false;
this._UISizeDot[i].Visible = show;
}
}
}
private void SetUISizeDotsPosition()
{
int left, width, height, top;
left = this._Owner.Left;
top = this._Owner.Top;
width = this._Owner.Width;
height = this._Owner.Height;
this._UISizeDot[0].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[1].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[2].Location = new Point(left + width + DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[3].Location = new Point(left + width + DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
this._UISizeDot[4].Location = new Point(left + width + DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[5].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top + height + DOT_SPACE);
this._UISizeDot[6].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[7].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
}
private void SetUISizeDotsPositionByMove(bool Show)
{
int left, width, height, top;
left = this._Owner.Left;
top = this._Owner.Top;
width = this._Owner.Width;
height = this._Owner.Height;
this._UISizeDot[0].Visible = Show;
this._UISizeDot[1].Visible = Show;
this._UISizeDot[2].Visible = Show;
this._UISizeDot[3].Visible = Show;
this._UISizeDot[4].Visible = Show;
this._UISizeDot[5].Visible = Show;
this._UISizeDot[6].Visible = Show;
this._UISizeDot[7].Visible = Show;
this._UISizeDot[0].BringToFront();
this._UISizeDot[1].BringToFront();
this._UISizeDot[2].BringToFront();
this._UISizeDot[3].BringToFront();
this._UISizeDot[4].BringToFront();
this._UISizeDot[5].BringToFront();
this._UISizeDot[6].BringToFront();
this._UISizeDot[7].BringToFront();
this._UISizeDot[0].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[1].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[2].Location = new Point(left + width + DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[3].Location = new Point(left + width + DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
this._UISizeDot[4].Location = new Point(left + width + DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[5].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top + height + DOT_SPACE);
this._UISizeDot[6].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[7].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
}
private void UISizeDot_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!((UISizeDot)sender).Movable)
{
return;
}
j++;
this.ShowUISizeDots(false);
this._BeginDrag = true;
this._ClickAtX = e.X;
this._ClickAtY = e.Y;
this._OldTop = this._Owner.Top;
this._OldLeft = this._Owner.Left;
this._NewTop = this._Owner.Top;
this._NewLeft = this._Owner.Left;
this._OldHeight = this._Owner.Height;
this._OldWidth = this._Owner.Width;
Rectangle rect = new Rectangle(this._NewLeft - 1, this._NewTop - 1, this._OldWidth + 2, this._OldHeight + 2);
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(Color.Black,2),rect);
this._OldRect = rect;
if (this.MouseDown != null)
this.MouseDown(sender, e);
}
private void UISizeDot_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!((UISizeDot)sender).Movable)
{
return;
}
if (this._BeginDrag)
{
int eX = e.X - this._ClickAtX;
int eY = e.Y - this._ClickAtY;
if (this._UISizeDot[0] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft + eX, this._NewTop + eY);
this._Owner.Size = new System.Drawing.Size(this._Owner.Width - eX, this._Owner.Height - eY);
}
else if (this._UISizeDot[1] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft, this._NewTop + eY);
this._Owner.Size = new System.Drawing.Size(this._Owner.Width, this._Owner.Height - eY);
}
else if (this._UISizeDot[2] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft, this._NewTop + eY);
this._Owner.Size = new System.Drawing.Size(this._Owner.Width + eX, this._Owner.Height - eY);
}
else if (this._UISizeDot[3] == sender)
{
this._Owner.Size = new System.Drawing.Size(this._Owner.Width + eX, this._Owner.Height);
}
else if (this._UISizeDot[4] == sender)
{
this._Owner.Size = new System.Drawing.Size(this._Owner.Width + eX, this._Owner.Height + eY);
}
else if (this._UISizeDot[5] == sender)
{
this._Owner.Size = new System.Drawing.Size(this._Owner.Width, this._Owner.Height + eY);
}
else if (this._UISizeDot[6] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft + eX, this._NewTop);
this._Owner.Size = new System.Drawing.Size(this._Owner.Size.Width - eX, this._Owner.Height + eY);
}
else if (this._UISizeDot[7] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft + eX, this._NewTop);
this._Owner.Size = new System.Drawing.Size(_Owner.Width - eX, this._Owner.Height);
}
this._NewTop = this._Owner.Top;
this._NewLeft = this._Owner.Left;
//this._OldHeight = this._Owner.Height;
//this._OldWidth = this._Owner.Width;
SetUISizeDotsPosition();
this._Owner.Refresh();
this._Owner.Parent.Refresh();
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(this._Owner.BackColor,2), this._OldRect);
Rectangle rect = new Rectangle(this._NewLeft - 1, this._NewTop - 1, this._Owner.Width + 2, this._Owner.Height + 2);
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(Color.Black,2), rect);
this._OldRect = rect;
}
if (this.MouseMove != null)
this.MouseMove(sender, e);
}
private void UISizeDot_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!((UISizeDot)sender).Movable)
{
return;
}
Hashtable OldWidth;
Hashtable OldHeight;
Hashtable NewWidth;
Hashtable NewHeight;
//Test.UIResizeCommand ResizeCommand;
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(this._Owner.BackColor,2),this._OldRect);
this.ShowUISizeDots(true);
//使用UIResizeCommand,这里主要是保存现场,这样可以方便实现Undo和Redo
if (this._OldHeight != this._Owner.Height || this._OldWidth != this._Owner.Width)
{
OldWidth = new Hashtable();
OldHeight = new Hashtable();
NewWidth = new Hashtable();
NewHeight = new Hashtable();
OldWidth.Add(this._Owner, this._OldWidth);
OldHeight.Add(this._Owner, this._OldHeight);
NewWidth.Add(this._Owner, this._Owner.Width);
NewHeight.Add(this._Owner, this._Owner.Height);
}
this._BeginDrag = false;
if (this.MouseUp != null)
this.MouseUp(sender, e);
}
}
3、设计器上控件与调整手柄的对应方法:
在我们的UISizeKnob中,有一个函数ShowUISizeDots(bool show)。这里的show参数就是表示,显示或者隐藏控件的调整手柄。
所以为了方便,我在前面的Form中增加这样的变量和函数:
变量private Hashtable _HashUISizeKnob负责缓存每个新增加的控件对应的UISizeKnob对象,因为一个Control只能对应一个UISizeKnob对象。
另外,我们怎么知道新增了控件呢,这里需要实现事件Control.ControlAdded,在这里是实现Form的ControlAdded事件。
Form的代码修改后如下:
//在Form中增加几个Button,分别命名为cmdArrow,cmdLabel,cmdTextBox,cmdComboBox,cmdGroupBox
public partial class Form1 : Form
{
private MouseHook _MouseHook;
//我们将所有的已经与具体控件关联了的UISizeKnob缓存在这个HashTable中
private Hashtable _HashUISizeKnob;
public Form1()
{
InitializeComponent();
this._MouseHook = new MouseHook(this);
this._HashUISizeKnob = new Hashtable();
//为了简洁明了,我们在ControlAdded中来设置具体控件和UISizeKnob的关联
this.ControlAdded += new ControlEventHandler(Form1_ControlAdded);
}
void Form1_ControlAdded(object sender, ControlEventArgs e)
{
if (!(e.Control is UISizeDot))
{
this._HashUISizeKnob.Add(e.Control, new UISizeKnob(e.Control));
//点击控件的时候,显示控件的选择
e.Control.Click += new EventHandler(Control_Click);
}
}
void Control_Click(object sender, EventArgs e)
{
//寿险清除已经选择的控件
foreach (UISizeKnob knob in this._HashUISizeKnob.Values)
{
knob.ShowUISizeDots(false);
}
try
{
((UISizeKnob)this._HashUISizeKnob[sender]).ShowUISizeDots(true);
}
catch { }
}
private void cmdArrow_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = null;
}
private void cmdLabel_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new Label();
}
private void cmdTextBox_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new TextBox();
}
private void cmdComboBox_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new ComboBox();
}
private void cmdGroupBox_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new GroupBox();
}
}
以上就是实现控件选择的关键部分,各位结合上面一篇,应该是很容易理解的,代码都是可运行的,自己拷贝过去就可以了。
所谓控件的选择,就是在设计器上某个控件被选中或者控件获得焦点(通过Tab调整控件焦点)的时候,在控件的四周显示出调整手柄。
如下图:
如上,通过控件的调整手柄,我们可以调整控件的宽度和高度。而实现这个调整手柄的关键点其实得益于vs2005控件的灵活性。因为这8个正方形的调整手柄其实就是8个控件。
所以我们本文的重点如下:
1、开发自定义的调整手柄控件,也就是这正方形控件;
2、组合这8个调整手柄控件,目标是使设计器上的控件与调整手柄完全解耦,调整手柄能够不做任何的修改就可以应用于所有的控件;
3、设计器上的控件与调整手柄的对应方法,也就是选择控件的时候,能够在控件周围显示调整手柄。
下面我们针对这3个重点,在前一篇《在容器上拖动鼠标增加控件》的基础上,实现控件的选择功能。
1、开发自定义的调整手柄控件:
这其实属于自定义控件开发的问题,你首先增加“用户控件”,把控件名命名为UISizeDot,把下面的代码直接拷贝进去就可以了,所以我不做过多的描述,这里直接把代码贴出来好了。
[ToolboxItem(false)]
public partial class UISizeDot : Control
{
private bool _movable;
private Pen pen = new Pen(Color.Black);
public UISizeDot()
{
InitializeComponent();
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.TabStop = false;
this._movable = true;
}
/// <summary>
/// UISizeDot的边框颜色
/// </summary>
public Color BorderColor
{
get { return pen.Color; }
set
{
this.pen = new Pen(value);
this.Refresh();
}
}
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: 在此处添加自定义绘制代码
//this.BackColor = Color.White;
pe.Graphics.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
// 调用基类 OnPaint
base.OnPaint(pe);
}
public bool Movable
{
get { return this._movable; }
set { this._movable = value; }
}
}
2、组合这8个自定义调整手柄控件:
这个功能的目的就是,就是将这8个调整手柄控件组合起来,为了描述以及开发上的方便,我们使用一个控件数组UISizeDot[]_UISizeDot = new UISizeDot(8),我们约定从左上角按照顺时针方向到又下角分别_UISizeDot[0]~ _UISizeDot[7],其它的不用说了,看代码吧:
public enum ENUM_UISizeMode
{
FixNone = 0, //不固定
FixLocation = 1, //固定左上角,这时只能改变两边
FixHeight = 2, //固定高
FixWidth = 3, //固定宽
FixBoth = 4 //长宽都固定
}
public class UISizeKnob
{
private const int DOT_WIDTH = 7; //UISizeDot宽度
private const int DOT_HEIGHT = 7; //UISizeDot高度
private const int DOT_SPACE = 0; //UISizeDot与_Owner的距离
private const int DOT_COUNT = 8; //要显示的UISizeDot数
private System.Windows.Forms.Control _Owner;
private UISizeDot[] _UISizeDot;
private int _OldTop;
private int _OldLeft;
private int _NewTop;
private int _NewLeft;
private int _OldWidth;
private int _OldHeight;
private int _ClickAtX;
private int _ClickAtY;
private ENUM_UISizeMode _UISizeMode;
private bool _BeginDrag;
private Rectangle _OldRect;
private Color _DotColor = Color.White; //UISizeDot默认颜色为白色
private Color _DotBorderColor = Color.Black; //UISizeDot默认边框颜色为黑色
public event System.Windows.Forms.MouseEventHandler MouseDown = null;
public event System.Windows.Forms.MouseEventHandler MouseMove = null;
public event System.Windows.Forms.MouseEventHandler MouseUp = null;
private int j=0;
private bool _IsShow = false;
public UISizeKnob(System.Windows.Forms.Control owner)
{
this._Owner = owner;
this._NewTop = owner.Top;
this._NewLeft = owner.Left;
this._OldWidth = owner.Width;
this._OldHeight = owner.Height;
InitUISizeDots();
}
public bool IsShow
{
get { return this._IsShow; }
}
public Color DotColor
{
get { return this._DotColor; }
set
{
this._DotColor = value;
this._DotBorderColor = Color.FromArgb(Math.Abs(Convert.ToInt32(value.R) - 255), Math.Abs(Convert.ToInt32(value.G) - 255), Math.Abs(Convert.ToInt32(value.B) - 255));
}
}
/// <summary>
/// 注销
/// </summary>
public void Dispose()
{
for (int i = 0; i < this._UISizeDot.Length; i++)
{
this._UISizeDot[i].Dispose();
}
}
/// <summary>
/// this._Owner的大小改变模式
/// </summary>
public ENUM_UISizeMode UISizeMode
{
get { return this._UISizeMode; }
set { this._UISizeMode = value; }
}
private void InitUISizeDots()
{
this._UISizeDot = new UISizeDot[DOT_COUNT];
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i] = new UISizeDot();
this._UISizeDot[i].Width = DOT_WIDTH;
this._UISizeDot[i].Height = DOT_HEIGHT;
this._UISizeDot[i].Visible = false;
this._Owner.Parent.Controls.Add(this._UISizeDot[i]);
this._UISizeDot[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.UISizeDot_MouseDown);
this._UISizeDot[i].MouseMove += new System.Windows.Forms.MouseEventHandler(this.UISizeDot_MouseMove);
this._UISizeDot[i].MouseUp += new System.Windows.Forms.MouseEventHandler(this.UISizeDot_MouseUp);
}
this._UISizeDot[0].Cursor = System.Windows.Forms.Cursors.SizeNWSE;
this._UISizeDot[1].Cursor = System.Windows.Forms.Cursors.SizeNS;
this._UISizeDot[2].Cursor = System.Windows.Forms.Cursors.SizeNESW;
this._UISizeDot[3].Cursor = System.Windows.Forms.Cursors.SizeWE;
this._UISizeDot[4].Cursor = System.Windows.Forms.Cursors.SizeNWSE;
this._UISizeDot[5].Cursor = System.Windows.Forms.Cursors.SizeNS;
this._UISizeDot[6].Cursor = System.Windows.Forms.Cursors.SizeNESW;
this._UISizeDot[7].Cursor = System.Windows.Forms.Cursors.SizeWE;
SetUISizeDotsPosition();
}
public void ShowUISizeDots(bool show)
{
this._IsShow = show;
//2006-10-05:将此函数中所有的this._UISizeDot.Length全部替换成8
if (show)
{
SetUISizeDotsPositionByMove(false);
}
else
{
this._Owner.Parent.SuspendLayout();
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].Visible = show;
}
this._Owner.Parent.ResumeLayout();
return;
}
if (this._UISizeMode == ENUM_UISizeMode.FixNone)
{
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].BorderColor = this._DotBorderColor;
this._UISizeDot[i].BackColor = this._DotColor;
this._UISizeDot[i].Visible = show;
}
}
else if (this._UISizeMode == ENUM_UISizeMode.FixLocation)
{
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].BorderColor = this._DotBorderColor;
this._UISizeDot[i].BackColor = this._DotColor;
this._UISizeDot[i].Visible = show;
}
this._UISizeDot[0].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[0].Movable = false;
this._UISizeDot[1].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[1].Movable = false;
this._UISizeDot[2].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[2].Movable = false;
this._UISizeDot[6].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[6].Movable = false;
this._UISizeDot[7].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[7].Movable = false;
}
else if (this._UISizeMode == ENUM_UISizeMode.FixHeight)
{
this._UISizeDot[0].Visible = false;
this._UISizeDot[1].Visible = false;
this._UISizeDot[2].Visible = false;
this._UISizeDot[3].BorderColor = this._DotBorderColor;
this._UISizeDot[3].BackColor = this._DotColor;
this._UISizeDot[3].Refresh();
this._UISizeDot[3].Visible = show;
this._UISizeDot[4].Visible = false;
this._UISizeDot[5].Visible = false;
this._UISizeDot[6].Visible = false;
this._UISizeDot[7].BorderColor = this._DotBorderColor;
this._UISizeDot[7].BackColor = this._DotColor;
this._UISizeDot[7].Refresh();
this._UISizeDot[7].Visible = show;
}
else if (this._UISizeMode == ENUM_UISizeMode.FixWidth)
{
this._UISizeDot[0].Visible = false;
this._UISizeDot[1].BorderColor = this._DotBorderColor;
this._UISizeDot[1].BackColor = this._DotColor;
this._UISizeDot[1].Visible = show;
this._UISizeDot[1].Refresh();
this._UISizeDot[2].Visible = false;
this._UISizeDot[3].Visible = false;
this._UISizeDot[4].Visible = false;
this._UISizeDot[5].BorderColor = this._DotBorderColor;
this._UISizeDot[5].BackColor = this._DotColor;
this._UISizeDot[5].Visible = show;
this._UISizeDot[5].Refresh();
this._UISizeDot[6].Visible = false;
this._UISizeDot[7].Visible = false;
}
else if (this._UISizeMode == ENUM_UISizeMode.FixBoth)
{
for (int i = 0; i < DOT_COUNT; i++)
{
this._UISizeDot[i].BorderColor = this._DotBorderColor;
this._UISizeDot[i].BackColor = System.Drawing.Color.FromArgb(9, 55, 119);
this._UISizeDot[i].Movable = false;
this._UISizeDot[i].Visible = show;
}
}
}
private void SetUISizeDotsPosition()
{
int left, width, height, top;
left = this._Owner.Left;
top = this._Owner.Top;
width = this._Owner.Width;
height = this._Owner.Height;
this._UISizeDot[0].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[1].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[2].Location = new Point(left + width + DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[3].Location = new Point(left + width + DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
this._UISizeDot[4].Location = new Point(left + width + DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[5].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top + height + DOT_SPACE);
this._UISizeDot[6].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[7].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
}
private void SetUISizeDotsPositionByMove(bool Show)
{
int left, width, height, top;
left = this._Owner.Left;
top = this._Owner.Top;
width = this._Owner.Width;
height = this._Owner.Height;
this._UISizeDot[0].Visible = Show;
this._UISizeDot[1].Visible = Show;
this._UISizeDot[2].Visible = Show;
this._UISizeDot[3].Visible = Show;
this._UISizeDot[4].Visible = Show;
this._UISizeDot[5].Visible = Show;
this._UISizeDot[6].Visible = Show;
this._UISizeDot[7].Visible = Show;
this._UISizeDot[0].BringToFront();
this._UISizeDot[1].BringToFront();
this._UISizeDot[2].BringToFront();
this._UISizeDot[3].BringToFront();
this._UISizeDot[4].BringToFront();
this._UISizeDot[5].BringToFront();
this._UISizeDot[6].BringToFront();
this._UISizeDot[7].BringToFront();
this._UISizeDot[0].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[1].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[2].Location = new Point(left + width + DOT_SPACE, top - DOT_HEIGHT - DOT_SPACE);
this._UISizeDot[3].Location = new Point(left + width + DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
this._UISizeDot[4].Location = new Point(left + width + DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[5].Location = new Point(left + width / 2 - DOT_WIDTH / 2, top + height + DOT_SPACE);
this._UISizeDot[6].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height + DOT_SPACE);
this._UISizeDot[7].Location = new Point(left - DOT_WIDTH - DOT_SPACE, top + height / 2 - DOT_HEIGHT / 2);
}
private void UISizeDot_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!((UISizeDot)sender).Movable)
{
return;
}
j++;
this.ShowUISizeDots(false);
this._BeginDrag = true;
this._ClickAtX = e.X;
this._ClickAtY = e.Y;
this._OldTop = this._Owner.Top;
this._OldLeft = this._Owner.Left;
this._NewTop = this._Owner.Top;
this._NewLeft = this._Owner.Left;
this._OldHeight = this._Owner.Height;
this._OldWidth = this._Owner.Width;
Rectangle rect = new Rectangle(this._NewLeft - 1, this._NewTop - 1, this._OldWidth + 2, this._OldHeight + 2);
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(Color.Black,2),rect);
this._OldRect = rect;
if (this.MouseDown != null)
this.MouseDown(sender, e);
}
private void UISizeDot_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!((UISizeDot)sender).Movable)
{
return;
}
if (this._BeginDrag)
{
int eX = e.X - this._ClickAtX;
int eY = e.Y - this._ClickAtY;
if (this._UISizeDot[0] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft + eX, this._NewTop + eY);
this._Owner.Size = new System.Drawing.Size(this._Owner.Width - eX, this._Owner.Height - eY);
}
else if (this._UISizeDot[1] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft, this._NewTop + eY);
this._Owner.Size = new System.Drawing.Size(this._Owner.Width, this._Owner.Height - eY);
}
else if (this._UISizeDot[2] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft, this._NewTop + eY);
this._Owner.Size = new System.Drawing.Size(this._Owner.Width + eX, this._Owner.Height - eY);
}
else if (this._UISizeDot[3] == sender)
{
this._Owner.Size = new System.Drawing.Size(this._Owner.Width + eX, this._Owner.Height);
}
else if (this._UISizeDot[4] == sender)
{
this._Owner.Size = new System.Drawing.Size(this._Owner.Width + eX, this._Owner.Height + eY);
}
else if (this._UISizeDot[5] == sender)
{
this._Owner.Size = new System.Drawing.Size(this._Owner.Width, this._Owner.Height + eY);
}
else if (this._UISizeDot[6] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft + eX, this._NewTop);
this._Owner.Size = new System.Drawing.Size(this._Owner.Size.Width - eX, this._Owner.Height + eY);
}
else if (this._UISizeDot[7] == sender)
{
this._Owner.Location = new System.Drawing.Point(this._NewLeft + eX, this._NewTop);
this._Owner.Size = new System.Drawing.Size(_Owner.Width - eX, this._Owner.Height);
}
this._NewTop = this._Owner.Top;
this._NewLeft = this._Owner.Left;
//this._OldHeight = this._Owner.Height;
//this._OldWidth = this._Owner.Width;
SetUISizeDotsPosition();
this._Owner.Refresh();
this._Owner.Parent.Refresh();
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(this._Owner.BackColor,2), this._OldRect);
Rectangle rect = new Rectangle(this._NewLeft - 1, this._NewTop - 1, this._Owner.Width + 2, this._Owner.Height + 2);
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(Color.Black,2), rect);
this._OldRect = rect;
}
if (this.MouseMove != null)
this.MouseMove(sender, e);
}
private void UISizeDot_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (!((UISizeDot)sender).Movable)
{
return;
}
Hashtable OldWidth;
Hashtable OldHeight;
Hashtable NewWidth;
Hashtable NewHeight;
//Test.UIResizeCommand ResizeCommand;
//this._Owner.Parent.CreateGraphics().DrawRectangle(new Pen(this._Owner.BackColor,2),this._OldRect);
this.ShowUISizeDots(true);
//使用UIResizeCommand,这里主要是保存现场,这样可以方便实现Undo和Redo
if (this._OldHeight != this._Owner.Height || this._OldWidth != this._Owner.Width)
{
OldWidth = new Hashtable();
OldHeight = new Hashtable();
NewWidth = new Hashtable();
NewHeight = new Hashtable();
OldWidth.Add(this._Owner, this._OldWidth);
OldHeight.Add(this._Owner, this._OldHeight);
NewWidth.Add(this._Owner, this._Owner.Width);
NewHeight.Add(this._Owner, this._Owner.Height);
}
this._BeginDrag = false;
if (this.MouseUp != null)
this.MouseUp(sender, e);
}
}
3、设计器上控件与调整手柄的对应方法:
在我们的UISizeKnob中,有一个函数ShowUISizeDots(bool show)。这里的show参数就是表示,显示或者隐藏控件的调整手柄。
所以为了方便,我在前面的Form中增加这样的变量和函数:
变量private Hashtable _HashUISizeKnob负责缓存每个新增加的控件对应的UISizeKnob对象,因为一个Control只能对应一个UISizeKnob对象。
另外,我们怎么知道新增了控件呢,这里需要实现事件Control.ControlAdded,在这里是实现Form的ControlAdded事件。
Form的代码修改后如下:
//在Form中增加几个Button,分别命名为cmdArrow,cmdLabel,cmdTextBox,cmdComboBox,cmdGroupBox
public partial class Form1 : Form
{
private MouseHook _MouseHook;
//我们将所有的已经与具体控件关联了的UISizeKnob缓存在这个HashTable中
private Hashtable _HashUISizeKnob;
public Form1()
{
InitializeComponent();
this._MouseHook = new MouseHook(this);
this._HashUISizeKnob = new Hashtable();
//为了简洁明了,我们在ControlAdded中来设置具体控件和UISizeKnob的关联
this.ControlAdded += new ControlEventHandler(Form1_ControlAdded);
}
void Form1_ControlAdded(object sender, ControlEventArgs e)
{
if (!(e.Control is UISizeDot))
{
this._HashUISizeKnob.Add(e.Control, new UISizeKnob(e.Control));
//点击控件的时候,显示控件的选择
e.Control.Click += new EventHandler(Control_Click);
}
}
void Control_Click(object sender, EventArgs e)
{
//寿险清除已经选择的控件
foreach (UISizeKnob knob in this._HashUISizeKnob.Values)
{
knob.ShowUISizeDots(false);
}
try
{
((UISizeKnob)this._HashUISizeKnob[sender]).ShowUISizeDots(true);
}
catch { }
}
private void cmdArrow_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = null;
}
private void cmdLabel_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new Label();
}
private void cmdTextBox_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new TextBox();
}
private void cmdComboBox_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new ComboBox();
}
private void cmdGroupBox_Click(object sender, EventArgs e)
{
SettingService.Instance.SelectedToolBoxControl = new GroupBox();
}
}
以上就是实现控件选择的关键部分,各位结合上面一篇,应该是很容易理解的,代码都是可运行的,自己拷贝过去就可以了。
相关文章推荐
- C#基础系列:开发自己的窗体设计器(实现控件的选择)
- C#基础系列:开发自己的窗体设计器(实现控件的拖动)
- C#基础系列:开发自己的窗体设计器(实现控件的拖动)
- C#基础系列:开发自己的窗体设计器(实现控件的拖动)
- C#基础系列:开发自己的窗体设计器(在容器上拖动鼠标增加控件)
- C#基础系列:开发自己的窗体设计器(在容器上拖动鼠标增加控件)
- C#基础系列:开发自己的窗体设计器(在容器上拖动鼠标增加控件)
- C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)
- C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)
- C#基础系列:开发自己的窗体设计器(总纲)
- 转 C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)
- C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)
- C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)
- C#里WinForm开发中如何实现控件随窗体大小的改变而自动适应其改变
- C#基础系列:实现自己的ORM(ORM的基础概念)
- C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)
- C#里WinForm开发中如何实现控件随窗体大小的改变而自动适应其改变
- C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)
- C#基础系列——委托实现简单设计模式
- C#里WinForm开发中如何实现控件随窗体大小的改变而自动适应其改变