Chú ý rng hot động này din ra trc tiếp bên trong phương thc th lý s kin
MouseMove. Vic v ch được thc hin nếu phn chn hin ti thay đổi. Đối vi mt
đon mã đơn gin, bn có th làm mt hiu lc toàn b form mi khi con tr chut di
chuyn vào trong hoc ra khi mt vùng và th lý tt c vic v trong phương thc th
s kin Form.Paint, nhưng điu này dn đến vic phi v nhiu hơn và to nên hin
tượng rung hình (flicker) khi toàn b form được v li.
1.1 To form có hình dng tùy biến
V
V
Bn cn to mt form hoc điu kim không phi hình ch nht.
#
#
To mt đối tượng System.Drawing.Region có hình dng như bn mun, và
gán nó vào thuc tính Form.Region hoc Control.Region.
Để to mt form hoc điu kim không phi hình ch nht, trước hết bn cn định nghĩa
hình dng mình mun. Cách tiếp cn d nht là s dng đối tượng
System.Drawing.Drawing2D.GraphicsPath, nó có th điu tiết bt k s kết hp nào ca
các hình ellipse, ch nht, và cung khép kín. Bn có th thêm các shape vào mt đối
tượng GraphicsPath bng các phương thc như AddEllipse, AddRectangle, và
AddClosedCurve. Mt khi đã hoàn tt vic định nghĩa hình dng như mong mun, bn có
th to mt đối tượng Region t GraphicsPath này—ch cn trình ra GraphicsPath trong
phương thc khi dng ca lp Region. Cui cùng, bn có th gán Region vào thuc tính
Form.Region hoc Control.Region.
Ví d dưới đây trình bày cách to mt form có hình dáng bt thường (xem hình 8.3) bng
hai cung tròn (hai cung này đưc chuyn thành mt figure khép kín bng phương thc
GraphicsPath.CloseAllFigures).
Hình 8.3 Form không phi hình ch nht
using System;
using System.Windows.Forms;
using System.Drawing;
The image part with relationsh ip ID rI d5 was not fo und in the file.
using System.Drawing.Drawing2D;
public class IrregularForm : System.Windows.Forms.Form {
private System.Windows.Forms.Button cmdClose;
private System.Windows.Forms.Label label1;
// (B qua phn mã designer.)
private void IrregularForm_Load(object sender, System.EventArgs e) {
GraphicsPath path = new GraphicsPath();
Point[] pointsA = new Point[] {new Point(0, 0),
new Point(40, 60), new Point(this.Width - 100, 10)};
path.AddCurve(pointsA);
Point[] pointsB = new Point[]
{new Point(this.Width - 40, this.Height - 60),
new Point(this.Width, this.Height),
new Point(10, this.Height)};
path.AddCurve(pointsB);
path.CloseAllFigures();
this.Region = new Region(path);
}
private void cmdClose_Click(object sender, System.EventArgs e) {
this.Close();
}
}
Đối vi ví d to điu kim không phi hình ch nht, bn hãy tham kho mc 8.4.
1.2 To điu kim có hình dng tùy biến
V
V
Bn cn to mt shape mà người dùng có th thao tác vi nó trên form như kéo
rê, thay đổi kích thước....
#
#
To mt điu kim tùy biến, và chép đè painting logic để v shape. Gán shape
ca bn vào thuc tính Control.Region. Kế đó, bn có th s dng Region này
để thc hin “hit testing”.
Nếu mun to mt giao din người dùng phc tp kết hp nhiu phn t được v tùy
biến, bn cn có phương cách để theo vết các phn t này và cho phép người dùng tương
tác vi chúng. Cách tiếp cn d nht trong .NET là to mt điu kim chuyên bit bng
cách dn xut mt lp t System.Windows.Forms.Control. Kế đó, bn có th tùy biến
phương cách mà điu kim này đưc v da theo tp các s kin cơ bn ca nó.
Điu kim được trình bày dưới đây mô t mt hình ellipse đơn gin trên form. Tt c các
điu kim đều được liên hp vi mt vùng ch nht trên form, do đó điu kim
EllipseShape s to mt ellipse lp đầy các đường biên này (được cp thông qua thuc
tính Control.ClientRectangle). Mt khi shape đã được to, thuc tính Control.Region
được thiết lp da theo biên trên ellipse. Điu này bo đảm các s kin như MouseMove,
MouseDown, Click... s xy ra ch khi chut trên ellipse, ch không phi toàn b hình
ch nht.
Dưới đây là phn mã đầy đủ ca lp EllipseShape:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
public class EllipseShape : System.Windows.Forms.Control {
private GraphicsPath path = null;
private void RefreshPath() {
// To GraphicsPath cho shape và áp dng nó vào
// điu kim bng cách thiết lp thuc tính Region.
path = new GraphicsPath();
path.AddEllipse(this.ClientRectangle);
this.Region = new Region(path);
}
protected override void OnResize(System.EventArgs e) {
base.OnResize(e);
RefreshPath();
this.Invalidate();
}
protected override void OnPaint
(System.Windows.Forms.PaintEventArgs e) {
base.OnPaint(e);
if (path != null) {
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.FillPath(new SolidBrush(this.BackColor), path);
e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);
}
}
}
Bn có th định nghĩa điu kim EllipseShape trong mt Class Library Assembly độc lp
để nó có th được thêm vào hp công c ca Microsoft Visual Studio .NETđược s
dng lúc thiết kế. Tuy nhiên, ngay c không thc hin bước này, cũng dng to được
mt ng dng th nghim đơn gin. Ví d dưới đây to hai ellipse và cho phép người
dùng kéo rê c hai vòng quanh form bng cách gi chut xung và di chuyn con tr.
Hình 8.4 Kéo rê các điu kim có hình dng tùy biến trên form
public class SpriteTest : System.Windows.Forms.Form {
// (B qua phn mã designer.)
// Các c dùng để theo vết chut khi chế độ kéo rê được kích hot.
private bool isDraggingA = false;
The image part with relationsh ip ID rI d6 was not fo und in the file.
private bool isDraggingB = false;
// Các điu kim có hình dng ellipse.
private EllipseShape ellipseA, ellipseB;
private void SpriteTest_Load(object sender, System.EventArgs e) {
// To và cu hình c hai ellipse.
ellipseA = new EllipseShape();
ellipseA.Width = ellipseA.Height = 100;
ellipseA.Top = ellipseA.Left = 30;
ellipseA.BackColor = Color.Red;
this.Controls.Add(ellipseA);
ellipseB = new EllipseShape();
ellipseB.Width = ellipseB.Height = 100;
ellipseB.Top = ellipseB.Left = 130;
ellipseB.BackColor = Color.Azure;
this.Controls.Add(ellipseB);
// Gn c hai ellipse vào cùng tp các phương thc
// th lý s kin.
ellipseA.MouseDown += new MouseEventHandler(Ellipse_MouseDown);
ellipseA.MouseUp += new MouseEventHandler(Ellipse_MouseUp);
ellipseA.MouseMove += new MouseEventHandler(Ellipse_MouseMove);
ellipseB.MouseDown += new MouseEventHandler(Ellipse_MouseDown);
ellipseB.MouseUp += new MouseEventHandler(Ellipse_MouseUp);
ellipseB.MouseMove += new MouseEventHandler(Ellipse_MouseMove);
}
private void Ellipse_MouseDown(object sender, MouseEventArgs e) {
// Thu ly ellipse gây ra s kin này.
Control control = (Control)sender;
if (e.Button == MouseButtons.Left) {
control.Tag = new Point(e.X, e.Y);