NET User Interfaces in Csharp Windows Forms and Custom Controls [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

NET User Interfaces in Csharp Windows Forms and Custom Controls [Electronic resources] - نسخه متنی

Matthew MacDonald

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید



























Hit Testing


In Chapter 11, you saw how you could build a simple drawing application by dynamically adding controls. An alternative (and potentially more lightweight) approach is to use GDI+ drawing structures. However, squares, ellipses, curves, and other shapes have no ability to capture mouse actions and raise the typical MouseDown and Click events. Instead, you need to intercept these events using the containing object (typically a form), and then manually determine if a shape was clicked. This process is known as hit testing.

.NET provides basic hit testing support through a Contains() method that's built into the Rectangle structure. It examines a supplied x and y coordinate, Point object, or Rectangle object, and returns true if it is located inside the Rectangle.

However, there are a couple of quirks that take some getting used to with Rectangle hit testing:



A Rectangle is a combination of points (defined by a top-left corner, width, and height). It doesn't necessarily correspond to a region on the screen— that depends on whether you've drawn some sort of shape based on the Rectangle with one of the GDI+ drawing methods.



The Rectangle is the only structure that supports hit testing. That means that if you create another shape (like a region or ellipse based on a rectangle), you either need to convert its coordinates into a Rectangle object, or retain the original Rectangle for later use.



The next example uses hit testing with the square-drawing program developed earlier. When the user right-clicks the form, the code loops through the collection of squares, and displays a message box for each one that contains the clicked point (see Figure 12-17).


// Reacts to the Form.MouseDown event.
private void DrawSquare_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Add a square and update the screen.
Rectangle square = new Rectangle(e.X, e.Y, 20, 20);
squares.Add(square);
this.Invalidate(square);
}
else if (e.Button == MouseButtons.Right)
{
// Search for the clicked square.
int squareNumber = 0;
foreach (Rectangle square in squares)
{
squareNumber++;
if (square.Contains(e.X, e.Y))
{
MessageBox.Show("Point inside square #" +
squareNumber.ToString());
}
}
}
}


Figure 12-17: Hit testing with squares

Once you have determined which square was clicked, you could modify it and then invalidate the form, or allow drag-and-drop as featured in Chapter 11.


Tip

The Rectangle also provides methods I don't consider here. For example, you can use Intersect() to return a Rectangle representing where two Rectangles intersect, Offset() to move it, and Inflate() to enlarge it.


Hit Testing Nonrectangular Shapes


.NET does provide some help if you need to perform hit testing with a nonrectangular object. If you use the GraphicsPath object to create a shape (or combination of shapes), you can rely on the indispensable IsVisible() method, which accepts a point and returns true if this point is contained inside a closed figure in the GraphicsPath. This method works equally well, whether you click inside a prebuilt closed figure (like a square, ellipse, polygon, and so on), or if you click inside a figure you created yourself with line segments using the StartFigure() and CloseFigure() methods of the GraphicsPath object.


private void GraphicsPathExample_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
path = new GraphicsPath();
path.StartFigure();
path.AddArc(10, 10, 100, 100, 20, 50);
path.AddLine(20, 50, 70, 230);
path.CloseFigure();
path.AddEllipse(120, 50, 80, 80);
e.Graphics.FillPath(Brushes.White, path);
e.Graphics.DrawPath(Pens.Black, path);
}
// Reacts to the Form.MouseDown event.
private void GraphicsPathExample_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (path.IsVisible(e.X, e.Y))
{
MessageBox.Show("You clicked inside the figure.");
}
}

Figure 12-18 shows a successful test of hit-testing with a nonrectangular shape. This technique is expanded in the next chapter into the basic framework for an advanced drawing program.


Figure 12-18: Hit testing a nonrectangular path



/ 142