您的位置:首页 > 编程语言 > C#

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

}

}

以上就是实现控件选择的关键部分,各位结合上面一篇,应该是很容易理解的,代码都是可运行的,自己拷贝过去就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐