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

Visual Basic 2005 Design and Development - Chapter 12 pot

32 294 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

Tiêu đề Attributes and XML Comments
Trường học Visual Basic University
Chuyên ngành Computer Science
Thể loại Chương
Năm xuất bản 2007
Thành phố New York
Định dạng
Số trang 32
Dung lượng 836,01 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The following code fragment applies the Description, ReadOnly, and DefaultValueattributes to the FirstNameproperty: _Public Property FirstName As String.... Browsable This attribute det

Trang 1

Attributes and XML

Comments

The Properties window and IntelliSense do a remarkable job of figuring out how your objectsand their properties work For example, suppose your program uses the following code to definethe JobTypesenumerated values and the AssignJobsubroutine:

Public Enum JobTypesDesign

DocumentationDevelopmentTestingDebuggingEnd EnumPrivate 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 AssignJobsubroutine’s signature below the cursor, itdisplays the list of possible JobTypesvalues that you could use for the subroutine’s first parame-ter, and it even displays the numeric value of the currently selected JobTypesvalue

Figure 12-1: IntelliSense automatically displays a subroutine’s signature and lists possible JobTypesvalues

Trang 2

Similarly, the Properties window automatically discovers the types of the properties provided by a 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

com-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 AssignJobssubroutine, 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 itdoesn’t know what the parameter is for

By using attributes and XML comments, you can give additional information that IntelliSense and editorssuch as the Properties window can use to provide extra support for developers In most cases, adding thissupport 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 candownload 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 bycode generators, editors, and other processes that manipulate the code itself For example, the Propertieswindow 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, XMLserialization 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, 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/

how-cpconretrievinginformationstoredinattributes.asp.

Attributes can decorate many different kinds of programming entities, including modules, classes, tures, subroutines, functions, properties, fields, enumerated types, and method parameters You can onlyapply an attribute to an item for which it was designed

struc-For example, the Browsableattribute determines whether a property or event should be visible in theProperties window You can apply the Browsableattribute 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 beforethe code item The following code fragment shows how you might add a Descriptionattribute to aclass’s FirstNameproperty:

Trang 3

Imports System.ComponentModel

<Description(“The employee’s first or given name”)> _Public Property FirstName() As String

End PropertyThe Descriptionattribute class is contained in the System.ComponentModelnamespace so the codeimports System.ComponentModelto make using the attribute easier The call to the Descriptionattribute’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 canomit this last part for convenience and to make the code less cluttered For example, the class that pro-vides the Descriptionattribute is named DescriptionAttribute Normally, you don’t need toworry 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 codeitem The following code fragment applies the Description, ReadOnly, and DefaultValueattributes

to the FirstNameproperty:

<Description(“The employee’s first or given name”), _[ReadOnly](True), _

DefaultValue(“(missing)”)> _Public Property FirstName() As String

Notice square brackets around the ReadOnlyattribute’s name This lets Visual Basic distinguish betweenthe attribute name and Visual Basic’s ReadOnlykeyword

An alternative technique is to include each attribute within its own set of pointy brackets, as shown inthe following code I prefer this version because it is a little easier to read, you don’t need to worry aboutmatching up the commas properly, and you can work with each attribute separately For example, youcould delete the line containing the DefaultValueattribute, 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 Manyare useful only under very specific circumstances, so there are many that you will probably never need

to use

Trang 4

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 aremostly 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 andedit properties and events

AmbientValue

This attribute indicates that a property gets its value from another source unless it is overridden Forexample, controls typically use the Font, ForeColor, and BackColorproperties used by their parentcontrols unless you override them

The following code makes the BoxColorproperty ambient:

End GetSet(ByVal value As Color)m_BoxColor = valueEnd Set

End Property

The property get procedure checks the m_BoxColorvariable If no value has been assigned to the variable,and if the control has a parent, then the procedure returns the parent’s ForeColorproperty

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, pose you build a component with a CurrentPriceproperty that uses a Web Service to get a stock price

sup-at run-time It might not make sense to display the stock price sup-at design time

The following code fragment hides the CurrentPriceproperty from the Properties window:

<Browsable(False)> _

Public Property CurrentPrice() As Single

Category

The Categoryproperty 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 anythingelse to define a new category Simply type a new category name into a Categoryattribute and theProperties window will make a new category for it

Trang 5

<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 youhave the Textproperty of a Labelselected and then click a TextBox, the Textproperty is still selected

If the newly selected control doesn’t have the selected property, the Properties window selects the trol’s default property

con-The following code sets the UserControl1class’s default property to DrawingFlags:

<DefaultProperty(“DrawingFlags”)> _Public Class UserControl1

Private Const DEFAULT_TITLE As String = “Untitled”

Private m_Title As String = DEFAULT_TITLE

<DefaultValue(DEFAULT_TITLE)> _Public Property Title() As String

Using the DefaultValueattribute 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’stype 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 anImageproperty:

<DefaultValue(GetType(Image), Nothing)> _Public Property StatusImage() As Image

Description

The Descriptionattribute sets the text displayed below the Properties window when the property isselected The following code places the FirstNameproperty in the “Name Values”category and givesthe property a description

Trang 6

<Category(“Name Values”)> _

<Description(“The employee’s first or given name.”)> _

Public Property FirstName() As String

The following code makes the Properties window display the RuntimeUserproperty with the nameCustomer:

<DisplayName(“Customer”)> _Public Property RuntimeUser() As Person

Trang 7

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 Thefollowing code allows the developer to see the OutsideTemperatureproperty 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 aregrayed out and the value is not editable

Figure 12-3: The ReadOnlyattribute makes the Propertieswindow 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, thenwhen you design for different locales in the form designer, the property’s localized values are saved intothe appropriate resource files

The following code makes the ReportLanguageproperty localizable:

<Localizable(True)> _Public Property ReportLanguage() As String

NotifyParentPropertyAttribute

This attribute determines whether a parent property is notified when this child property is changed Forexample, if a property is a Structurethat contains other properties, you can use this attribute on theStructure’s properties

Trang 8

The following code makes the FirstNameproperty notify a parent property when it is changed:

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 Aboutproperty with a parenthesizedname This is a dummy property that doesn’t store or display any value However, it has an associatededitor class named AboutEditor That makes the Properties window display an ellipsis to the right ofthe property’s value If you click the ellipsis, the AboutEditordisplays a simple Aboutdialog

‘ A dummy property to display an About dialog

<ParenthesizePropertyName(True)> _

<Editor(GetType(AboutEditor), GetType(UITypeEditor))> _

Public Property About() As String

GetReturn NothingEnd Get

Set(ByVal value As String)End Set

End Property

Download the UseAttributesexample program and look at the code to see exactly how the AboutEditorclass works See the section “Displaying and Editing PolyPolyline” in Chapter 11 for more information onproperty editors

You can see the DatabasePasswordproperty 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 valueisn’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 allowsthe Properties window to display an additional tab that can provide a customized view of the compo-nent’s properties

Trang 9

Figure 12-4 shows the Properties window displaying a tab named Test Properties This tab displays onlyproperties 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 UserControl1class with theTestPropertiesTabclass:

<PropertyTabAttribute(GetType(TestPropertiesTab), PropertyTabScope.Document)> _Public Class UserControl1

The following code shows how the TestPropertiesTabclass works:

Imports System.ComponentModel

‘ This tab lists only properties in the Test Properties category

Public Class TestPropertiesTabInherits 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.PropertyDescriptorCollectionDim props_in As PropertyDescriptorCollection

If attributes Is Nothing Thenprops_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( _

Trang 10

TypeDescriptor.CreateProperty( _

props_in(i).ComponentType, _props_in(i), _

Nothing) _)

End IfNext iReturn props_outEnd Function

Public Overloads Overrides Function GetProperties(ByVal component As Object) _

As System.ComponentModel.PropertyDescriptorCollectionReturn Me.GetProperties(component, Nothing)End Function

‘ Provides the name for the property tab

Public Overrides ReadOnly Property TabName() As StringGet

Return “Test Properties”

End GetEnd Property

‘ Provides an image for the property tab

Public Overrides ReadOnly Property Bitmap() As System.Drawing.BitmapGet

Return My.Resources.TestPropertiesEnd Get

End PropertyEnd Class

The parent class PropertyTabdoes most of the work

The class overrides its inherited GetPropertiesmethod to return a collection of objects describing theproperties that should be displayed on the tab The routine loops through the components and addsthose in the Test Properties category to the result collection

The tab class’s GetPropertiesfunction calls its GetPropertiesmethod and returns the result

The read-only TabNameproperty returns the name of the tab This is the text displayed in the tooltipshown in Figure 12-4

Finally, the read-only Bitmapproperty returns the bitmap displayed for the tab in the Properties window

In this example, the property returns the Bitmapstored in the TestPropertiesresource (You can load this example at www.vb-helper.com/one_on_one.htm.)

down-RefreshPropertiesAttribute

This attribute determines how the Properties window refreshes its display when the property’s valuechanges The ContactViewercontrol described in Chapter 11 uses this attribute to update its propertydisplay The control has a property of type Contact The Contactclass has FirstName, LastName,andPhoneproperties The program uses a type converter to allow the Properties window to display

Trang 11

these sub-properties It also flags the FirstName, LastName, and Phoneproperties with the RefreshPropertiesAttributeto make the Properties window update the Contactproperty’s display when-ever one of its sub-properties changes.

The following code shows how the example applies this attribute to the FirstNameproperty:

<RefreshProperties(RefreshProperties.Repaint)> _Public Property FirstName() As String

<TypeConverter(GetType(PolyPolylineConverter))> _Public Property PolyPolyline() As PolyPolyline

See the section “Displaying and Editing PolyPolyline” in Chapter 11 for more information on thisattribute

Helping the Form Designer

The attributes described in the following sections provide extra help for the form designer

Docking

This attribute indicates whether a control should automatically dock to fill its container if it is created in

a container that holds no other controls

The following code makes the UserControl1control dock to fill its container:

<Docking(DockingBehavior.AutoDock)> _Public Class UserControl1

Trang 12

This attribute sets the bitmap displayed for a component in the toolbox The following code sets the box bitmap for the UserControl1control to the tbxUserControl1resource in the assembly containingthe UserControl1class:

This attribute determines the type of toolbox item displayed for a component, or whether a toolbox item

is displayed at all This is useful, for example, if you want to build a constituent control for use in anothercontrol, but you don’t want to make the constituent control directly available to other developers

The following code makes the ToolNotInToolboxcomponent not appear in the toolbox:

<ToolboxItem(False)> _

Public Class ToolNotInToolbox

Helping the Code Editor

The attributes described in these sections help the code editor They provide additional informationabout items so that the code editor can display them, and provide help appropriately at design time andwhile debugging

infor-Conditional

This attribute can make the run-time system ignore calls to a method when the program executes Thefollowing code demonstrates the Conditionalattribute:

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, _ByVal e As System.EventArgs) Handles MyBase.Load

Trang 13

IfCondition1()IfCondition2()End Sub

<Conditional(“DEBUG”)> _Private Sub IfCondition1()MessageBox.Show(“IfCondition1”)End Sub

<Conditional(“Condition2”)> _Private Sub IfCondition2()MessageBox.Show(“IfCondition2”)End Sub

End ClassThe code defines two conditional subroutines: IfCondition1and IfCondition2 IfCondition1isconditional on the DEBUGcompilation constant, so it executes only if the program is running in debugmode

IfCondition2is conditional on the Condition2compilation constant To set this constant, click My Properties, select the Compile tab, and click the Advanced Compile Options button to displaythe dialog shown in Figure 12-5 Enter the constant’s definition in the “Custom constants” text box

double-Figure 12-5: You can use the Advanced Compiler Settings dialog to define compilation constants

If a conditional method’s condition is not defined as True, the method is compiled into the executableprogram, but calls to it are ignored at run-time

Trang 14

This attribute determines when a property is visible to IntelliSense You can set this to Always(appears

in all IntelliSense tabs), Advanced(appears in the All tab, but not the Common tab), or Never(doesn’tappear in either IntelliSense tab) The following code makes the RuntimeUserproperty appear inIntelliSense’s All tab:

<EditorBrowsable(EditorBrowsableState.Advanced)> _

Public Property RuntimeUser() As Person

Flags

This attribute indicates that an enumerated type should be treated as a bit field that allows combinations

of its values To allow developers to make bitwise combinations of values, you should set the values topowers of 2: 1, 2, 4, 8, 16, and so forth You should also create a Nonevalue set to 0 If you like, you candefine common combinations of values

The following code defines values that tell a control whether to draw a box, X, or cross The valueSpidermeans both an X and a cross

<Flags()> _

Public Enum DrawingFlagValues

None = 0Box = 1

X = 2Cross = 4Spider = X Or CrossEnd Enum

Trang 15

This attribute tells IntelliSense to hide a module’s name You can still type the module’s name if youlike, and IntelliSense will show the items inside the module The following code hides the name ofHiddenModulefrom IntelliSense:

<HideModuleName()> _Module HiddenModule

ProvideProperty

This attribute gives the name of a property that an extender provider implements for its client controls.The following code indicates that the ExtraTagProviderclass provides the ExtraTagproperty:

<ProvideProperty(“ExtraTag”, GetType(Control))> _Public Class ExtraTagProvider

For more information on building extender providers, see the section “Building Extender Providers” inChapter 10

Obsolete

This attribute indicates that an item is obsolete Optionally, you can provide a message for Visual Studio

to display in the Error List window and as a tooltip when the developer hovers the mouse over the codethat uses the obsolete item

The following code marks the SortCustomerArraysubroutine as obsolete If the code uses this tine, Visual Studio displays the warning, “This method has been replaced with SortArray,” as shown inFigure 12-6

subrou-<Obsolete(“This method has been replaced with SortArray”)> _Public Sub SortCustomerArray(ByVal customer_array() As Customer)MessageBox.Show(“SortCustomerArray”)

End Sub

Figure 12-6: The code editor displays an error message if you use an obsolete subroutine

This attribute can also indicate whether using the obsolete item should generate a warning or an error Forexample, when you replace a subroutine in a new release of your software, you can make calls to the oldversion raise a warning so developers can find and fix them In the next release of your code, you can makethe old call cause an error so that developers who have not yet updated their code are forced to do so

This attribute can also be a useful tool in managing your own code If you want to replace a routine with

a better version, you can mark the old version as obsolete That gives you a little extra documentation onthe routine, and Visual Studio will nag you about using the routine until you get around to removing it

Trang 16

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, whereasthe previously described attributes are used by the Properties window, form designer, code editor, andother design-time tools

The reason Visual Basic uses attributes here instead of some more run-time–oriented technique is thatserializers use reflection at run-time to examine the objects they are serializing Attributes decorate aclass, property, or other item so that the serializer can learn about the attributes at run-time

OnDeserializing, OnDeserialized, OnSerializing, and OnSerialized

These attributes indicate that a class method should be executed during and after serialization ordeserialization

The following code fragment shows part of the Personclass The OnSerializingMethodsubroutinehas the OnSerializingattribute, so it is called when a Personobject is serialized In this example,the subroutine sets the Personobject’s FirstNameproperty to “OnSerializingMethod”

<Serializable()> _

Public Class Person

<OnSerializing()> _Friend Sub OnSerializingMethod(ByVal context As StreamingContext)FirstName = “OnSerializingMethod”

End Sub

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

TỪ KHÓA LIÊN QUAN