ASP. NET interactive bitmap Form Design (5)

Source: Internet
Author: User

Maintain two lists
Because we need to Change the fill color of the object to implement the Change fill to hot pink button, we maintain two lists of printable objects: one list is all objects, and the other list is filled objects. We use the ArrayList class for both lists. The ArrayList Object contains a group of Object references-such an ArrayList can contain any type of mixture in the system.

This is actually not helpful-we hope that the ArrayList will only include printable/populated objects. Therefore, we set the ArrayList object to private, and then set the process of adding an object to the list as a method. This method only accepts one DShape.

When the Add method is used to Add objects to the list, we Add all objects to wholeList and check whether the objects should be added to the filledList set.

Remember that the Add method (and list) has the type security feature: It only accepts DShape (or a type derived from DShape, such as all the types we created above ). You cannot add integers or strings to the list, so that we can know that the list only contains printable objects. It is very convenient to know this!

Draw item

We also have a DrawList Method for drawing objects in the list on the Graphics object passed as the parameter. This method has two cases: if the list is empty, it draws a string, indicating that the list is empty. If the list is not empty, it uses a for each constructor to traverse the list and call Draw on each object. The actual traversal and drawing code are much simpler, as shown in Visual Basic below.


Visual Basic
. NET Dim d As DShape
For Each d In wholeList
D. Draw (g)
Next


C # The code is almost identical (of course, there are fewer lines ).


C #
Foreach (DShape d in wholeList)
D. Draw (g );


Because the list is encapsulated, we know it has the type security feature, so you can only call the Draw method without checking the object type.

Back to the filling list
Finally, our Change fills to hot pink (Change fill color to pink) button requires an array of references to all the objects that can be filled to Change its FillBrushColor attribute. Although you can write a method to traverse the list and change the color to the passed value, this time Dr. GUI selects to return an object reference array. Fortunately, the ArrayList class has a ToArray method, which can be used to create an array for passing. This method gets the expected array element type, which can be passed back to the required type, IFillable array.


C #

Public IFillable [] GetFilledList (){
Return (IFillable []) filledList. ToArray (typeof (IFillable ));
}

Visual Basic

. NET Public Function GetFilledList () As IFillable ()
Return filledList. ToArray (GetType (IFillable ))
End Function


In both languages, we use a built-in operator to obtain the Type object of the given Type-in C #, It is typeof (IFillable); in Visual Basic, is GetType (IFillable ).

The caller uses this array to traverse the array that can be filled with object references. For example, the following Visual Basic code changes the fill color to Pink:


Dim filledList As IFillable () = drawingList. GetFilledList ()
Dim I As IFillable
For Each I In filledList
I. FillBrushColor = Color. HotPink
Next

Helper methods and classes used to break down public code
You may notice that the Draw and Fill methods have a lot of common code. To be exact, the code for creating a pen or paint brush in each class, the code for creating a Try/Finally block, and the Code for clearing a pen or paint brush are the same-the only difference is the actual call for drawing or filling. method. (Because the using syntax in C # is very concise, the number of redundant code is not obvious .) In Visual Basic. NET, each line of code may have a line of special code that is the same in all implementations.

In short, if there are a lot of repeated code, you need to look for the decomposition of public code to form a public subroutine shared by all classes. There are many such methods, and Dr. GUI is very happy to show you two of them. The first method is only used for classes. The second method can be used for classes or interfaces. In this example, it is only used for interfaces.

Method 1: Call a virtual method at a public entry point
In the first method, we use the fact that classes (different from interfaces) can contain code. Therefore, we provide an implementation of the Draw method for creating a pen, an exception handler and Dispose, and then call the abstract/MustOverride Method for drawing. Specifically, we changed the DShapes class to adapt to the new Draw method, and then declared the new JustDraw method:


Public MustInherit Class DShape
Draw is not virtual. It seems unusual ......
Draw should have been abstract (MustOverride ).
But this method is the drawing frame, not the drawing Code itself,
The drawing code is completed in JustDraw.
Note that this means that these classes have
Different interfaces, although they do the same work.
Public Sub Draw (ByVal g As Graphics)
Dim p = New Pen (penColor)
Try
JustDraw (g, p)
Finally
P. Dispose ()
End Try
End Sub
Here is the part that needs to become a polymorphism-so it is abstract
Protected MustOverride Sub JustDraw (ByVal g As Graphics ,_
ByVal p As Pen)
Protected bounding As Rectangle
Protected penColor As Color should also have attributes
Methods such as moving and resizing should also be available.
End Class

It is worth noting that the Draw method is not virtual/Overridable. Because all derived classes will complete this part of the drawing in the same way (if drawing on Graphics [as defined in this example], you must assign and clear the pen ), therefore, it does not need to be virtual/Overridable.

In fact, Dr. GUI assumes that Draw should not be virtual/Overridable in this example. To overwrite the Draw behavior (not just the JustDraw behavior), you can set it to virtual/Overridable. However, in this example, there is no reason to overwrite the Draw behavior. If programmers are encouraged to overwrite, there is a hidden risk-they may not properly process the pen, or use other methods to Draw objects rather than calling JustDraw, this violates the assumptions we have built into the class. Therefore, setting Draw to a non-virtual mode (this option is not available in Brand J, By the way) may reduce code flexibility, but be more reliable-Dr. GUI believes that in this example, this is very worthwhile.

The typical Implementation of JustDraw is as follows:


Protected Overrides Sub JustDraw (ByVal g As Graphics, ByVal p As Pen)
G. DrawEllipse (p, bounding)
End Sub

As you can see, we have obtained the expected concise implementation of the derived class. (The implementation in the padding class is a little more complicated-we will see it later .)

Please note that we have added an additional public method JustDraw in the interface. In addition to the Graphics object to be drawn, This method also references the Pen object we created in Draw. This method must be abstract/MustOverride, so it must be public.

This is not a big problem, but it does change the public interface of the class. Therefore, even if the method for splitting public code is very simple and convenient, you should select other methods as much as possible to avoid changing public interfaces.

Method 2: Call the public helper method using the virtual method and use the callback
When implementing the Fill method of the interface, the Code complexity is similar: each six lines of code may have a line of special code that is the same in all implementations. However, we cannot put public implementations into interfaces because interfaces are only declarations and do not contain code or data. In addition, the method listed above is unacceptable because it will change the interface -- we may not want this, or because it is an interface created by someone else, we cannot change it!

Therefore, we need to write a helper method to set and callback our class for actual filling. In this example, Dr. GUI places the code in a separate class so that the code can be used by any class. (If you use this method to implement Draw, you can use the helper method as the private method in the abstract base class .)

We will not expand it further. The following is the class we created:


Note that the help provided by the delegate still has polymorphism.
Class FillHelper
Public Delegate Sub Filler (ByVal g As Graphics, ByVal B As Brush)
Shared Sub SafeFill (ByVal I As IFil

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.