1. Trang chủ
  2. » Công Nghệ Thông Tin

Visual Basic 2005 Design and Development - Chapter 12 pot

32 289 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 32
Dung lượng 836,01 KB

Nội dung

Attributes and XML Comments The Properties window and IntelliSense do a remarkable job of figuring out how your objects and their properties work. For example, suppose your program uses the following code to define the JobTypes enumerated values and the AssignJob subroutine: Public Enum JobTypes Design Documentation Development Testing Debugging End Enum Private Sub AssignJob(ByVal job_type As JobTypes) ‘ End Sub If you type “AssignJob(“ in the code window, IntelliSense automatically displays all of the infor- mation shown in Figure 12-1. It shows the AssignJob subroutine’s signature below the cursor, it displays the list of possible JobTypes values that you could use for the subroutine’s first parame- ter, and it even displays the numeric value of the currently selected JobTypes value. Figure 12-1: IntelliSense automatically displays a subroutine’s signature and lists possible JobTypes values. 17_053416 ch12.qxd 1/2/07 6:33 PM Page 329 Similarly, the Properties window automatically discovers the types of the properties provided by a com- ponent, and supplies appropriate editors in many cases. For example, it automatically provides drop- downs for selecting colors or enumerated values, dialogs for selecting files or colors, and a combination of sub-properties and a dialog for selecting fonts. Visual Studio provides all of this support automatically. Although all of these tools are extremely useful, Visual Studio cannot deduce the intent of your code. IntelliSense can list the signature of the AssignJobs subroutine, but it cannot guess the routine’s pur- pose. It can display a list of the possible values that you might use for the routine’s parameter, but it doesn’t know what the parameter is for. By using attributes and XML comments, you can give additional information that IntelliSense and editors such as the Properties window can use to provide extra support for developers. In most cases, adding this support takes only a few seconds, but giving developers a better understanding of what the code is sup- posed to do can save you hours of frustrating debugging and maintenance. This chapter is divided into two parts that describe some useful attributes and XML comments. (You can download examples demonstrating most of these attributes and XML comments at www.vb-helper.com/ one_on_one.htm .) Attributes Visual Studio uses attributes to “decorate” code with extra information. This information is mostly used by code generators, editors, and other processes that manipulate the code itself. For example, the Properties window uses many attributes to decide how a particular item should be displayed and edited. Run-time code can also examine attributes to learn more about a particular item. For example, XML serialization routines can examine an object’s attributes to learn more about how the object should be serialized. In fact, you can make your code examine an object’s attributes. This is a relatively unusual need, how- ever, so it’s not described here. For more information, search the online help for “Retrieving Information Stored in Attributes,” or look at msdn.microsoft.com/library/en-us/cpguide/html/ cpconretrievinginformationstoredinattributes.asp . Attributes can decorate many different kinds of programming entities, including modules, classes, struc- tures, subroutines, functions, properties, fields, enumerated types, and method parameters. You can only apply an attribute to an item for which it was designed. For example, the Browsable attribute determines whether a property or event should be visible in the Properties window. You can apply the Browsable attribute to a class, but it will be ignored. To apply an attribute, you enclose a call to the attribute class’s constructor inside pointy brackets before the code item. The following code fragment shows how you might add a Description attribute to a class’s FirstName property: 330 Part II: Meta-Development 17_053416 ch12.qxd 1/2/07 6:33 PM Page 330 Imports System.ComponentModel <Description(“The employee’s first or given name”)> _ Public Property FirstName() As String End Property The Description attribute class is contained in the System.ComponentModel namespace so the code imports System.ComponentModel to make using the attribute easier. The call to the Description attribute’s constructor takes a single parameter giving the property’s description. The call is enclosed in pointy brackets. The attribute is followed by a line-continuation character, so the attribute is actually part of the same line of code as the property’s declaration. Putting attributes on separate lines makes the code easier to read. The class name for an attribute generally ends with the word “Attribute.” In Visual Basic, you can omit this last part for convenience and to make the code less cluttered. For example, the class that pro- vides the Description attribute is named DescriptionAttribute. Normally, you don’t need to worry about this, but if you want to learn more about the class, you should search the online help for “DescriptionAttribute class.” You can include multiple attributes inside the pointy brackets to apply more than one attribute to a code item. The following code fragment applies the Description, ReadOnly, and DefaultValue attributes to the FirstName property: <Description(“The employee’s first or given name”), _ [ReadOnly](True), _ DefaultValue(“(missing)”)> _ Public Property FirstName() As String Notice square brackets around the ReadOnly attribute’s name. This lets Visual Basic distinguish between the attribute name and Visual Basic’s ReadOnly keyword. An alternative technique is to include each attribute within its own set of pointy brackets, as shown in the following code. I prefer this version because it is a little easier to read, you don’t need to worry about matching up the commas properly, and you can work with each attribute separately. For example, you could delete the line containing the DefaultValue attribute, or add a new attribute line without modi- fying the others. <Description(“The employee’s first or given name”)> _ <[ReadOnly](True)> _ <DefaultValue(“(missing)”)> _ Public Property FirstName() As String The .NET Framework defines more than 300 attribute classes, so they are not all described here. Many are useful only under very specific circumstances, so there are many that you will probably never need to use. 331 Chapter 12: Attributes and XML Comments 17_053416 ch12.qxd 1/2/07 6:33 PM Page 331 The following sections described some of the attribute classes that I have found the most useful, grouped by the types of tasks they perform. They describe the attributes’ purposes and the code items that are mostly likely to use the attributes. They also include a brief example. Helping the Properties Window These attributes help the Properties window do a better job. They tell the window how to display and edit properties and events. AmbientValue This attribute indicates that a property gets its value from another source unless it is overridden. For example, controls typically use the Font, ForeColor, and BackColor properties used by their parent controls unless you override them. The following code makes the BoxColor property ambient: <AmbientValue(GetType(Color), Nothing)> _ Public Property BoxColor() As Color Get If (m_BoxColor = Nothing) AndAlso (Me.Parent IsNot Nothing) Then Return Me.Parent.ForeColor Else Return m_BoxColor End If End Get Set(ByVal value As Color) m_BoxColor = value End Set End Property The property get procedure checks the m_BoxColor variable. If no value has been assigned to the variable, and if the control has a parent, then the procedure returns the parent’s ForeColor property. Browsable This attribute determines whether a property or event is visible in the Properties window. This is useful if you want to make a property or event available at run-time but not at design time. For example, sup- pose you build a component with a CurrentPrice property that uses a Web Service to get a stock price at run-time. It might not make sense to display the stock price at design time. The following code fragment hides the CurrentPrice property from the Properties window: <Browsable(False)> _ Public Property CurrentPrice() As Single Category The Category property determines the category in which a property or event is grouped in the Properties window when you click the window’s Categorized button. You don’t need to do anything else to define a new category. Simply type a new category name into a Category attribute and the Properties window will make a new category for it. 332 Part II: Meta-Development 17_053416 ch12.qxd 1/2/07 6:33 PM Page 332 <Category(“Name Values”)> _ Public Property FirstName() As String DefaultProperty This attribute indicates a component’s default property. When you select a control in the form designer, the Properties window initially selects the same property that it already had selected. For example, if you have the Text property of a Label selected and then click a TextBox, the Text property is still selected. If the newly selected control doesn’t have the selected property, the Properties window selects the con- trol’s default property. The following code sets the UserControl1 class’s default property to DrawingFlags: <DefaultProperty(“DrawingFlags”)> _ Public Class UserControl1 DefaultValue This attribute sets the default value for a property. If the developer right-clicks the property in the Properties window and selects Reset, Visual Studio sets the property’s value to the default value. Usually, you should set the property to the same default value when the object is initially created. The following code defines a constant to hold the default value for the Title property. It uses the private variable m_Title to hold the property’s value, and it initializes the value to the default value in the vari- able’s declaration. The DefaultValue attribute uses the same value, so if the developer resets the Title property, its value is set to “Untitled.” Private Const DEFAULT_TITLE As String = “Untitled” Private m_Title As String = DEFAULT_TITLE <DefaultValue(DEFAULT_TITLE)> _ Public Property Title() As String Using the DefaultValue attribute is straightforward for simple data types such as strings and singles. For properties that are objects, you must use a different attribute constructor that includes the object’s type and a string value that can be converted into that type. Usually, you should reset object properties to Nothing. The following code shows how to do this for an Image property: <DefaultValue(GetType(Image), Nothing)> _ Public Property StatusImage() As Image Description The Description attribute sets the text displayed below the Properties window when the property is selected. The following code places the FirstName property in the “Name Values” category and gives the property a description. 333 Chapter 12: Attributes and XML Comments 17_053416 ch12.qxd 1/2/07 6:33 PM Page 333 <Category(“Name Values”)> _ <Description(“The employee’s first or given name.”)> _ Public Property FirstName() As String Figure 12-2 shows the Properties window with the FirstName property selected. Notice the description at the bottom of the window. Notice also that the property is in the Property window’s Name Values section. Figure 12-2: The Description attribute determines the text displayed below the Properties window for a property. Designer This attribute associates a class with a designer class that is used to display smart tags on the form designer. The following code associates the ScribbleControl class with the ScribbleControl Designer class: <Designer(GetType(ScribbleControlDesigner))> _ Public Class ScribbleControl See the section “Displaying Smart Tags” in Chapter 11, “Property Support,” for more information about this attribute. DisplayName This attribute specifies the name that the Properties window should display for a property. You should try to give properties names that are meaningful to the developers who will use them, but you can use this property if you must. The following code makes the Properties window display the RuntimeUser property with the name Customer: <DisplayName(“Customer”)> _ Public Property RuntimeUser() As Person 334 Part II: Meta-Development 17_053416 ch12.qxd 1/2/07 6:33 PM Page 334 Editor This attribute associates a property with an editor class that can edit the property. See the section “Displaying and Editing LineWidth” in Chapter 11 for more information about this attribute. ReadOnly This attribute determines whether the developer can modify a property in the Properties window. The following code allows the developer to see the OutsideTemperature property but not modify it: <[ReadOnly](True)> _ Public Property OutsideTemperature() As Single Figure 12-3 shows the Properties window displaying this property. The property’s name and value are grayed out and the value is not editable. Figure 12-3: The ReadOnly attribute makes the Properties window display a property grayed out and not editable. Localizable This attribute determines whether a property’s value is saved in localized resource files. If this is False (the default), the property value is saved only once and is shared for all locales. If this is True, then when you design for different locales in the form designer, the property’s localized values are saved into the appropriate resource files. The following code makes the ReportLanguage property localizable: <Localizable(True)> _ Public Property ReportLanguage() As String NotifyParentPropertyAttribute This attribute determines whether a parent property is notified when this child property is changed. For example, if a property is a Structure that contains other properties, you can use this attribute on the Structure’s properties. 335 Chapter 12: Attributes and XML Comments 17_053416 ch12.qxd 1/2/07 6:33 PM Page 335 The following code makes the FirstName property notify a parent property when it is changed: <NotifyParentProperty(True)> _ Public Property Contact() As Contact ParenthesizePropertyName This attribute determines whether the property’s name is surrounded by parentheses in the Properties window. When the Properties window sorts properties alphabetically, those with parentheses are shown at the top, so this can make key properties easier to find. When the Properties window is grouping items by category, the parenthesized properties appear at the top of their category. The following code makes the Properties window display an About property with a parenthesized name. This is a dummy property that doesn’t store or display any value. However, it has an associated editor class named AboutEditor. That makes the Properties window display an ellipsis to the right of the property’s value. If you click the ellipsis, the AboutEditor displays a simple About dialog. ‘ A dummy property to display an About dialog. <ParenthesizePropertyName(True)> _ <Editor(GetType(AboutEditor), GetType(UITypeEditor))> _ Public Property About() As String Get Return Nothing End Get Set(ByVal value As String) End Set End Property Download the UseAttributes example program and look at the code to see exactly how the AboutEditor class works. See the section “Displaying and Editing PolyPolyline” in Chapter 11 for more information on property editors. PasswordPropertyText This attribute tells the Properties window to hide the property’s value with asterisks or some other password-masking character. The following code sets this attribute for the DatabasePassword property: <PasswordPropertyText(True)> _ Public Property DatabasePassword() As String You can see the DatabasePassword property in Figures 12-2 and 12-3. Note that the property’s value is still stored in plain text in the designer-generated code, so the value isn’t completely hidden. It just doesn’t jump out for people walking past the developer to see. PropertyTab This attribute associates a component class with a property tab class. The property tab class allows the Properties window to display an additional tab that can provide a customized view of the compo- nent’s properties. 336 Part II: Meta-Development 17_053416 ch12.qxd 1/2/07 6:33 PM Page 336 Figure 12-4 shows the Properties window displaying a tab named Test Properties. This tab displays only properties that are in the Test Properties category. Figure 12-4: The Test Properties tab displays only properties in the Test Properties category. The following code shows how the program associates the UserControl1 class with the TestPropertiesTab class: <PropertyTabAttribute(GetType(TestPropertiesTab), PropertyTabScope.Document)> _ Public Class UserControl1 The following code shows how the TestPropertiesTab class works: Imports System.ComponentModel ‘ This tab lists only properties in the Test Properties category. Public Class TestPropertiesTab Inherits PropertyTab ‘ Returns only the properties in the Test Properties category. Public Overloads Overrides Function GetProperties(ByVal component As Object, _ ByVal attributes() As System.Attribute) _ As System.ComponentModel.PropertyDescriptorCollection Dim props_in As PropertyDescriptorCollection If attributes Is Nothing Then props_in = TypeDescriptor.GetProperties(component) Else props_in = TypeDescriptor.GetProperties(component, attributes) End If Dim props_out As New PropertyDescriptorCollection(Nothing) Dim i As Integer For i = 0 To props_in.Count - 1 If props_in(i).Category = “Test Properties” Then ‘ Create a PropertyDescriptor for this property. props_out.Add( _ 337 Chapter 12: Attributes and XML Comments 17_053416 ch12.qxd 1/2/07 6:33 PM Page 337 TypeDescriptor.CreateProperty( _ props_in(i).ComponentType, _ props_in(i), _ Nothing) _ ) End If Next i Return props_out End Function Public Overloads Overrides Function GetProperties(ByVal component As Object) _ As System.ComponentModel.PropertyDescriptorCollection Return Me.GetProperties(component, Nothing) End Function ‘ Provides the name for the property tab. Public Overrides ReadOnly Property TabName() As String Get Return “Test Properties” End Get End Property ‘ Provides an image for the property tab. Public Overrides ReadOnly Property Bitmap() As System.Drawing.Bitmap Get Return My.Resources.TestProperties End Get End Property End Class The parent class PropertyTab does most of the work. The class overrides its inherited GetProperties method to return a collection of objects describing the properties that should be displayed on the tab. The routine loops through the components and adds those in the Test Properties category to the result collection. The tab class’s GetProperties function calls its GetProperties method and returns the result. The read-only TabName property returns the name of the tab. This is the text displayed in the tooltip shown in Figure 12-4. Finally, the read-only Bitmap property returns the bitmap displayed for the tab in the Properties window. In this example, the property returns the Bitmap stored in the TestProperties resource. (You can down- load this example at www.vb-helper.com/one_on_one.htm.) RefreshPropertiesAttribute This attribute determines how the Properties window refreshes its display when the property’s value changes. The ContactViewer control described in Chapter 11 uses this attribute to update its property display. The control has a property of type Contact. The Contact class has FirstName, LastName, and Phone properties. The program uses a type converter to allow the Properties window to display 338 Part II: Meta-Development 17_053416 ch12.qxd 1/2/07 6:33 PM Page 338 [...]... describe the code Chapter 13, “Documentation,” continues this topic by showing how you can write Visual Basic code that transforms this XML data into HTML files or Word documents 358 18_053416 pt03.qxd 1/2/07 6:33 PM Page 359 Part III Development In this Par t: Chapter 13 Documentation Chapter 14 Development Philosophy Chapter 15 Coding Standards Chapter 16 Bug Proofing Chapter 17 Testing Chapter 18 Deployment... top-of-the-line controls that provide complex visualization tools for hundreds or thousands of customers, it may well be worth the extra struggle to implement these advanced features If you are writing a simple control that you will use only once or twice, you can probably skip much of this and save yourself a lot of time and trouble 357 17_053416 ch12.qxd 1/2/07 6:33 PM Page 358 Part II: Meta -Development. .. parameter Figure 1 2-9 : IntelliSense displays param tag information about parameters 350 17_053416 ch12.qxd 1/2/07 6:33 PM Page 351 Chapter 12: Attributes and XML Comments Recommended Tags If you type three single quotes before a code element, Visual Basic fills in default XML tags that are appropriate for the element You can enter other tags within the XML comment to provide additional information Visual Studio... Meta -Development This chapter (and the four before it) dealt with meta -development These are topics that deal with tools that help developers perform their tasks They provide assistance for other programmers, not end users The chapters in the next section of the book are more user-oriented They cover development practices that bring better features and more stable applications to end users This chapter discussed... property’s value Figure 1 2-1 1 shows the Object Browser displaying information about the Form1 class’s DisplayMessage function Unfortunately, the Object Browser doesn’t understand XML comments such as , , or , so the sections can sometimes be poorly formatted 354 17_053416 ch12.qxd 1/2/07 6:33 PM Page 355 Chapter 12: Attributes and XML Comments Figure 1 2-1 1: The Object Browser displays... is placed without any identification between the opening Address tag and the open Zip tag CA98765 XML Comments Many of the attributes described so far have been around in previous versions of Visual Basic NET XML comments, however, were added in Visual Basic 2005 and were awaited eagerly by many experienced developers XML comments... ch12.qxd 1/2/07 6:33 PM Page 344 Part II: Meta -Development Helping Serialization The attributes described in these sections help determine how objects are serialized and deserialized These are a bit different from the attributes described so far, because they are used at run-time, whereas the previously described attributes are used by the Properties window, form designer, code editor, and other design- time... See the section “Displaying and Editing PolyPolyline” in Chapter 11 for more information on this attribute Helping the Form Designer The attributes described in the following sections provide extra help for the form designer DefaultEvent This attribute specifies a class’s default event When you double-click the control in the form designer, the code editor opens an event handler for this event The following... PersonComments is the root namespace, Person is the class, PrintLetter is the subroutine’s name) and the data types of its parameters Figure 1 2-7 : Check the “Generate XML documentation file” box to produce documentation automatically 349 17_053416 ch12.qxd 1/2/07 6:33 PM Page 350 Part II: Meta -Development The summary, param, and remarks tags contain values that were entered manually in the code Having built this... the application and process the XML file again Design- Time Support The second reason to use XML comments is that they give more information that IntelliSense can use to make it easier for developers to understand your code When a routine appears in the IntelliSense list, a tooltip displays the routine’s name and parameters, plus any information you entered in the summary XML tag Figure 1 2-8 shows the . form designer, code editor, and other design- time tools. The reason Visual Basic uses attributes here instead of some more run-time–oriented technique is that serializers use reflection at run-time. You can see the DatabasePassword property in Figures 1 2-2 and 1 2-3 . Note that the property’s value is still stored in plain text in the designer-generated code, so the value isn’t completely hidden have been around in previous versions of Visual Basic .NET. XML comments, however, were added in Visual Basic 2005 and were awaited eagerly by many experi- enced developers. XML comments allow

Ngày đăng: 14/08/2014, 11:20

TỪ KHÓA LIÊN QUAN