C # Control Development (2)

Source: Internet
Author: User
5. Basic Knowledge: use attribute to customize the display of the attribute window.
The display control mechanism is the same as that defined by IDL, but the metadata feature is added. The most common feature of control display is browsableattribute. By default, the Properties window displays all the public, readable (public, get, or set) attributes defined in the object and places them in "Miscellaneous (MISC) "category. The following is a simple component example:

Public class simplecomponent: system. componentmodel. Component
{

Private string data = "(none )";

Private bool datavalid = false;

Public String data

{

Get

{

Return data;

}

Set

{

If (value! = Data)

{

Datavalid = true;

Data = value;

}

}

}

Public bool isdatavalid

{

Get

{

// Perform some check on the data

//

Return datavalid;

}

}

}

This example is displayed in the Properties window:

Figure 1. Simple components displayed in the Properties window

In this example, simplecomponent has two attributes: Data and isdatavalid. In fact, because isdatavalid is read-only, it does not make much sense to display it here, and the designer does not need to know the value of this attribute in the design status. Therefore, we add the browsableattribute feature to the attribute window so that the attribute window does not display the attribute.

[Browsable (false)]

Public bool isdatavalid

{

Get

{

// Perform some check on the data

//

Return datavalid;

}

}

The compiler automatically adds the "attribute" character after the feature class name, so we canCode. Of course, entering "[browsableattribute (false)]" is the same effect. For attributes or classes without specified features, the compiler uses default features and default feature values to describe them. In this example, the default value of browsableattribute is true. This principle is also consistent with Visual Basic. net. The only difference between the two is Visual Basic.. net uses angle brackets ('<' and '>') to mark features, rather than brackets ('[' and ']') used in C #.

The compiler automatically adds the "attribute" character after the feature class name, so we can omit it in the code. Of course, entering "[browsableattribute (false)]" is the same effect. For attributes or classes without specified features, the compiler uses default features and default feature values to describe them. In this example, the default value of browsableattribute is true. This principle is also consistent with Visual Basic. net. The only difference between the two is Visual Basic.. net uses angle brackets ('<' and '>') to mark features, rather than brackets ('[' and ']') used in C #.

At the same time, note that in figure 1, the value of the data attribute "ABC" is in bold. This means that the attribute value is not the default value and will be saved when the designer generates code for form or control (a value assignment statement will be generated ). There is no need to generate the value assignment statement for the default attribute values. Generating code means increasing the initialization time (initializecomponent method) of the component and the size of the code file. So how does simplecomponent send the default notification attribute window? To implement this feature, we need to use the defaultvalueattribute feature to describe the attribute, so that we can assign a value to the attribute in the object builder. When the attribute window displays the attribute value, it compares the current value with the default value specified by defavaluvalueattribute. If the two are not the same, the value is displayed in bold. In the following example, if the value of the data attribute is not "(none)", it is displayed in bold.

[Defaultvalue ("(none)")]

Public String data

{

//...

}

We can also add more complex judgment logic to the attribute, instead of simply comparing some inherent values. This can be achieved by adding some special methods to the component. The name of the logical attribute judgment method must start with "shouldserialize", followed by the attribute name, and the return value of this method is "Boolean ". In this example, this method is called "shouldserializedata ". Add the following code to the simplecomponent component to achieve the same effect as defavaluvalueattribute, but it can have stronger logic code.

Private bool shouldserializedata ()

{

Return data! = "(None )";

}

Generally, attribute classification is more user-friendly for designers. We use the categoryattribute feature to classify attributes. This feature uses a simple category string. The Properties window displays the attributes in the category subitem. The category name can be determined by yourself.

[Defaultvalue ("(none)"), category ("sample")]

Public String data

{

//...

}

A common problem for component developers is how to localize the category string. Let's look at the categoryattribute class and we can see that its getlocalizedstring method provides such a function. To localize the category string, a new feature class is derived from the categoryattribute class. In this example, we obtain the localized category string indexed by key value from the string resource of the component. When you specify the categoryattribute attribute, replace the original category name with this key as the input parameter. In this way, the attribute window will call the getlocalizedstring method to query the categoryattribute of an attribute and pass the key value as a parameter. The returned attribute category name is displayed in the attribute window.

Internal class loccategoryattribute: categoryattribute

{

Public loccategoryattribute (string categorykey): Base (categorykey)

{

}

Protected override string getlocalizedstring (string key)

{

// Get the resource set for the current locale.

//

ResourceManager = new ResourceManager ();

String categoryname = NULL;

// Walk up the cultures until we find one

// This key as a resource as our category name

// If we reach the invariant culture, quit.

//

For (cultureinfo culture = cultureinfo. currentculture;

Categoryname = NULL &&

Culture! = Cultureinfo. invariantculture;

Culture = culture. Parent)

{

Categoryname = (string) ResourceManager. GetObject (Key, culture );

}

Return categoryname;

}

}

To use this localized category name, we need to first define a resource file containing this key and use this feature to the attribute.

[Loccategory ("samplekey")]

Public String data

{

//...

}

In the design window, if multiple components on form are selected, the property window displays their common attributes, which are differentiated by Component Attribute names and types. If you change the value of a common attribute, the attribute value of all selected components changes accordingly. In general, it is of little significance to include an attribute in the synthesis of other attributes. Generally, common attributes have unique values, such as the name of another component. When multiple components are selected, the value of common attributes is changed, and the attribute values of all selected components are changed. Therefore, you must specify that some attributes are not merged into common attributes. Mergablepropertyattribute can do this. As long as this feature parameter is set to false, you can hide this attribute when selecting multiple components. Naturally, its value will not change.

Some attribute values can affect other attribute values. For example, in the component that implements data binding, clear the value of datasource and the value of datamember. Refreshpropertiesattribute allows us to implement this function. Its default parameter is "NONE", that is, it does not affect other attributes. If other feature parameters are specified, the attribute window can change the attribute value while, automatically update values of other attributes. The other two values are repaint, which allows the attribute window to re-obtain the attribute values and re-draw them. The other is all, which means that the component needs to re-obtain the attribute value. If the value changes and the number of attributes increases or decreases, we need to use all. However, it should be noted that this is generally used in advanced scenarios and the speed is slower than repaint. Refreshproperties. repaint applies in most cases. It should be noted that this feature is used for attributes that cause changes, rather than adapted attributes.

Finally, defaproperpropertyattribute and defaulteventattribute are used at the class level, and they make the attribute window highlight these attributes and events. When selecting other components, the Properties window always tries to locate the same properties or events as the last selected component. If such an attribute or event is not found, it locates the input pointer to the attribute specified by defaproperpropertyattribute. In the event view, the event specified by defaulteventattribute is located. This event is also automatically used when you double-click a component.

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.