/// <summary> /// Summary description for Decorator. /// 装饰 Decorator Patterns /// 20220918 /// geovindu,Geovin Du,涂聚文 /// </summary> public interface Decorator { /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void mouseMove(object sender, MouseEventArgs e); /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void mouseEnter(object sender, EventArgs e); /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void mouseLeave(object sender, EventArgs e); /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void paint(object sender, PaintEventArgs e); }
/// <summary> /// 装饰 Decorator Patterns /// 20220918 /// geovindu,Geovin Du,涂聚文 /// </summary> public partial class CoolDecorator : Panel, Decorator { protected Control contl; protected Pen bPen, wPen, gPen; private bool mouse_over; protected float x1, y1, x2, y2; /// <summary> /// /// </summary> public CoolDecorator() { InitializeComponent(); } /// <summary> /// /// </summary> /// <param name="container"></param> public CoolDecorator(IContainer container) { container.Add(this); InitializeComponent(); } /// <summary> /// /// </summary> /// <param name="c"></param> /// <param name="baseC"></param> public CoolDecorator(Control c, Control baseC) { //the first control is the one layed out //the base control is the one whose paint method we extend //this allows for nesting of decorators contl = c; this.Controls.AddRange(new Control[] { contl }); c.Location = new Point(0, 0); this.Name = "deco" + contl.Name; this.Size = contl.Size; x1 = c.Location.X - 1; y1 = c.Location.Y - 1; x2 = c.Size.Width; y2 = c.Size.Height; //create the overwrite pens gPen = new Pen(c.BackColor, 2); bPen = new Pen(Color.Black, 1); wPen = new Pen(Color.White, 1); //mouse over, enter handler EventHandler evh = new EventHandler(mouseEnter); c.MouseHover += evh; c.MouseEnter += evh; c.MouseHover += evh; //mouse move handler c.MouseMove += new MouseEventHandler(mouseMove); c.MouseLeave += new EventHandler(mouseLeave); //paint handler catches button's paint baseC.Paint += new PaintEventHandler(paint); } /// <summary> /// /// </summary> /// <param name="p"></param> public void locate(Point p) { this.Location = p; contl.Location = new Point(0, 0); x1 = p.X; y1 = p.Y; } /// <summary> /// /// </summary> /// <param name="c"></param> public virtual void locate(Control c) { this.Location = c.Location; c.Location = new Point(0, 0); x1 = c.Location.X - 1; y1 = c.Location.Y - 1; x2 = c.Size.Width; y2 = c.Size.Height; } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void mouseMove(object sender, MouseEventArgs e) { mouse_over = true; } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void mouseEnter(object sender, EventArgs e) { mouse_over = true; this.Refresh(); } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void mouseLeave(object sender, EventArgs e) { mouse_over = false; this.Refresh(); } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public virtual void paint(object sender, PaintEventArgs e) { //draw over button to change its outline Graphics g = e.Graphics; const int d = 1; //draw over everything in gray first g.DrawRectangle(gPen, 0, 0, x2 - 1, y2 - 1); //draw black and white boundaries //if the mouse is over if (mouse_over) { g.DrawLine(bPen, 0, 0, x2 - d, 0); g.DrawLine(bPen, 0, 0, 0, y2 - 1); g.DrawLine(wPen, 0, y2 - d, x2 - d, y2 - d); g.DrawLine(wPen, x2 - d, 0, x2 - d, y2 - d); } } }
/// <summary> /// Summary description for SlashDeco. /// 装饰 Decorator Patterns /// 20220918 /// geovindu,Geovin Du,涂聚文 /// </summary> public class SlashDeco : CoolDecorator { private Pen rPen; /// <summary> /// /// </summary> /// <param name="c"></param> /// <param name="bc"></param> public SlashDeco(Control c, Control bc) : base(c, bc) { rPen = new Pen(Color.Red, 2); } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public override void paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; x1 = 0; y1 = 0; x2 = this.Size.Width; y2 = this.Size.Height; g.DrawLine(rPen, x1, y1, x2, y2); } }
/// <summary> /// 装饰 Decorator Patterns /// 20220918 /// geovindu,Geovin Du,涂聚文 /// </summary> public partial class DecoPanel : System.Windows.Forms.Panel { private Control c; private Pen bPen, wPen, gPen; private bool gotControl; private bool mouse_over; private float x1, y1, x2, y2; /// <summary> /// /// </summary> public DecoPanel() { InitializeComponent(); init(); } /// <summary> /// /// </summary> /// <param name="container"></param> public DecoPanel(IContainer container) { container.Add(this); InitializeComponent(); } /// <summary> /// /// </summary> private void init() { bPen = new Pen(System.Drawing.Color.Black, 1); wPen = new Pen(System.Drawing.Color.White, 1);// gotControl = false; //no control } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void ctMouseEnter(object sender, EventArgs e) { mouse_over = true; Refresh(); } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void ctMouseLeave(object sender, EventArgs e) { mouse_over = false; this.Refresh(); } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void ctMouseMove(object sender, MouseEventArgs e) { mouse_over = true; } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void ctPaint(object sender, PaintEventArgs e) { //draw over button to change its outline Graphics g = e.Graphics; const int d = 1; //draw over everything in gray first g.DrawRectangle(gPen, 0, 0, x2 - 1, y2 - 1); //draw black and white boundaries //if the mouse is over if (mouse_over) { g.DrawLine(bPen, 0, 0, x2 - d, 0); g.DrawLine(bPen, 0, 0, 0, y2 - 1); g.DrawLine(wPen, 0, y2 - d, x2 - d, y2 - d); g.DrawLine(wPen, x2 - d, 0, x2 - d, y2 - d); } } /// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { //This is where we find out about the control if (!gotControl) { //once only //get the control c = this.Controls[0]; //set the panel size //1 pixel bigger all around Size sz = new Size(); sz.Width = c.Size.Width + 2; sz.Height = c.Size.Height + 2; this.Size = sz; x1 = c.Location.X - 1; y1 = c.Location.Y - 1; x2 = c.Size.Width; y2 = c.Size.Height; //create the overwrite pen gPen = new Pen(c.BackColor, 2); gotControl = true; //only once //mouse over, enter handler EventHandler evh = new EventHandler(ctMouseEnter); c.MouseHover += evh; c.MouseEnter += evh; //mouse move handler c.MouseMove += new MouseEventHandler(ctMouseMove); c.MouseLeave += new EventHandler(ctMouseLeave); //paint handler catches button's paint c.Paint += new PaintEventHandler(ctPaint); } } }
窗体调用:
/// <summary> /// 装饰 Decorator Patterns /// 20220918 /// geovindu,Geovin Du,涂聚文 /// </summary> public partial class DecoratorPatternsForm : Form { private SlashDeco slash; /// <summary> /// /// </summary> private CoolDecorator cdec; /// <summary> /// /// </summary> private void init() { //save the position of the button Point pt = btButtonA.Location; //create a cool decorator cdec = new CoolDecorator(btButtonA, btButtonA); //decorate the cool decorator with a slash slash = new SlashDeco(cdec, btButtonA); slash.locate(pt); //add outside decorator to the layout //and remove the button from the layout this.Controls.AddRange(new System.Windows.Forms.Control[] { slash }); this.Controls.Remove(btButtonA); //this.Controls.AddRange(new System.Windows.Forms.Control[] {cdec}); } /// <summary> /// 装饰Decorator Patterns /// </summary> public DecoratorPatternsForm() { InitializeComponent(); init(); } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void DecoratorPatternsForm_Load(object sender, EventArgs e) { } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btQuit_Click(object sender, EventArgs e) { this.Close(); } /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btButtonA_Click(object sender, EventArgs e) { } }
输出:
点击前:、
点击后: