Document directory
- Create class xprop
- Create class xpropdescriptor
- Create class xprops
- Interface code
- Test
Target
The basic usage of PropertyGrid is to bind a fixed class to display the attributes and values of this class.
However, in some cases, you need to use PropertyGrid to bind a set of attributes/values, but this set of attributes/values is not suitable for writing a fixed class.
For example, you want to use PropertyGrid to bind data in XML. Or a table in the database.
Suppose you have 1000 XML files, and each XML has different attribute sets. You cannot write a class for each XML file.
Or a data table has 1000 records. The value of field a indicates the attribute name, and the value of field B indicates the attribute value. You cannot write a class and define 1000 attributes.
At this time, we hope to bind a dynamic set of attributes/values to the Property.
This VB 2005 instance tutorial solves this problem. To simplify the problem, we assume that you have prepared the data source as a Collection of properties/values ).
Instance Interface
First, we will design the following interface.
Enter data in Name and Value. Name indicates the attribute Name, and Value indicates the attribute Value. After you click the Add button, the entered information will be displayed in the PropertyGrid below;
Modify some property values in PropertyGrid. After you click Show, the modified value is stored in the custom property/value set (Collection) in the TextBox text box at the bottom of the screen).
The following table lists controls and attribute settings.
Object |
Control Type |
Attribute |
Attribute Value |
Xpgridwin |
Form |
Text |
Dynamic PropertyGrid-book.chinaz.com/html |
|
|
Size |
475,540 |
Label1 |
Label |
Location |
12, 12 |
|
|
Size |
35, 13 |
|
|
Text |
Name |
TxtName |
TextBox |
Location |
53, 9 |
|
|
Size |
100, 20 |
Label2 |
Label |
Location |
177, 12 |
|
|
Size |
34, 13 |
|
|
Text |
Value |
TxtValue |
TextBox |
Location |
217, 9 |
|
|
Size |
100, 20 |
CmdAdd |
Button |
Location |
380, 7 |
|
|
Size |
75, 23 |
|
|
Text |
Add |
CmdShow |
Button |
Location |
380, 36 |
|
|
Size |
75, 23 |
|
|
Text |
Show |
PGrid |
PropertyGrid |
Location |
12, 70 |
|
|
Size |
443,283 |
TxtShow |
TextBox |
Location |
13,360 |
|
|
Multiline |
True |
|
|
Size |
443,134 |
Program Design
The basic way to achieve this goal is to create a Collection class of attributes/Values and associate the objects of this class with PropertyGrid. At the same time, let PropertyGrid not analyze the attributes of this class, but use the custom attribute name and attribute value.
System. ComponentModel defines an interface ICustomTypeDescriptor, any Implements
When the class of this interface is bound to PropertyGrid, PropertyGrid does not analyze the attributes of this class, but uses the members implemented in the interface to construct the attribute window.
Based on the above analysis, the basic program design is:
- Define an xprop class to save a pair of attribute names/values. This class has two attributes: one is name, indicating the attribute name; the other is value, indicating the attribute value.
- Define an xprops class as a collection of xprop and implement the icustomtypedescriptor interface.
- In addition, to implement the required interface, you also need to define an xpropdescriptor class to correspond the attribute names and attribute values in xprop
Propertygrid. The xpropdescriptor class must be inherits icustomtypedescriptor,
Icustomtypedescriptor is an interface provided by. NET Framework.
Code
Create a file named XProps. vb and use the Class template. The file contains the following Imports.
Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Text
The following three classes will be created in this file:
- Xprop
- Xpropdescriptor
- Xprops
Create Class XProp
XProp is the property that you will use. PropertyGrid
One amazing thing is that attributes can be customized with great degrees of freedom. Here, we provide the simplest form. attributes include the Name and Value.
In the Properties window of PropertyGrid, Name indicates the attribute Name on the left and Value indicates the attribute Value on the right.
Public Class XProp
Private theName As String = ""
Private theValue As Object = Nothing
Public Property Name() As String
Get
Return theName
End Get
Set(ByVal value As String)
theName = value
End Set
End Property
Public Property Value() As Object
Get
Return theValue
End Get
Set(ByVal value As Object)
theValue = value
End Set
End Property
Public Overrides Function ToString() As String
Return "Name: " & Name & ", Value: " & Value
End Function
End Class
There is nothing special about this Class. The Overrides of ToString is used to display the content of the entire Class.
Create Class XPropDescriptor
XPropDescriptior is based on XProp and PropertyDescriptor.
. Propertydescriptor is in system. componentmodel and contains propertygrid
Interfaces corresponding to each attribute in. Xpropdescriptior maps the attributes in xprop to these interfaces.
Public Class XPropDescriptor
Inherits PropertyDescriptor
Private theProp As XProp
Public Sub New(ByVal prop As XProp, ByVal attrs() As Attribute)
MyBase.New(prop.Name, attrs)
theProp = prop
End Sub
Public Overrides Function CanResetValue(ByVal component As Object) As Boolean
Return False
End Function
Public Overrides ReadOnly Property ComponentType() As System.Type
Get
Return Me.GetType
End Get
End Property
Public Overrides Function GetValue(ByVal component As Object) As Object
Return theProp.Value
End Function
Public Overrides ReadOnly Property IsReadOnly() As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property PropertyType() As System.Type
Get
Return theProp.Value.GetType()
End Get
End Property
Public Overrides Sub ResetValue(ByVal component As Object)
' Do Nothing
End Sub
Public Overrides Sub SetValue(ByVal component As Object, ByVal value As Object)
theProp.Value = value
End Sub
Public Overrides Function ShouldSerializeValue(ByVal component As Object) As Boolean
Return False
End Function
End Class
In most cases, the default value is returned. Note the following parts.
- New
This part imports the xprop object into the class and stores it in the theprop variable, which serves as the basis for ing user attributes to the attributes used by propertygrid.
- Getvalue
Put the property values stored in xprop into propertygrid.
- Setvalue
Store the attribute values modified by the user in propertygrid to xprop.
- Propertytype
Specifies the type of this attribute. Propertygrid can use different types to select the corresponding Property Value dialog box.
Create Class XProps
Xprops is actually the collection of xprop. This is easy. You only need to use a line of code to inherit
System. Collections. Generic. List (of xprop. (I hope you understand the generic class.
In. NET Framework 2.0 .)
On the other hand, xprops needs to implement the interface of icustomtypedescriptor, so that the object of this class and propertygrid
When associating, propertygrid uses user-defined parts to form the Property Window, instead of using the program property of this class to form the Property Window.
Public Class XProps
Inherits List(Of XProp)
Implements ICustomTypeDescriptor
#Region "ICustomTypeDescriptor Implementation"
Public Function GetAttributes() As AttributeCollection _
Implements ICustomTypeDescriptor.GetAttributes
Return TypeDescriptor.GetAttributes(Me, True)
End Function
Public Function GetClassName() As String _
Implements ICustomTypeDescriptor.GetClassName
Return TypeDescriptor.GetClassName(Me, True)
End Function
Public Function GetComponentName() As String _
Implements ICustomTypeDescriptor.GetComponentName
Return TypeDescriptor.GetClassName(Me, True)
End Function
Public Function GetConverter() As TypeConverter _
Implements ICustomTypeDescriptor.GetConverter
Return TypeDescriptor.GetConverter(Me, True)
End Function
Public Function GetDefaultEvent() As EventDescriptor _
Implements ICustomTypeDescriptor.GetDefaultEvent
Return TypeDescriptor.GetDefaultEvent(Me, True)
End Function
Public Function GetDefaultProperty() As PropertyDescriptor _
Implements ICustomTypeDescriptor.GetDefaultProperty
Return TypeDescriptor.GetDefaultProperty(Me, True)
End Function
Public Function GetEditor(ByVal editorBaseType As System.Type) As Object _
Implements ICustomTypeDescriptor.GetEditor
Return TypeDescriptor.GetEditor(Me, editorBaseType, True)
End Function
Public Function GetEvents() As EventDescriptorCollection _
Implements ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, True)
End Function
Public Function GetEvents(ByVal attributes() As System.Attribute) _
As EventDescriptorCollection _
Implements ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, attributes, True)
End Function
Public Function GetProperties() As PropertyDescriptorCollection _
Implements ICustomTypeDescriptor.GetProperties
Return TypeDescriptor.GetProperties(Me, True)
End Function
Public Function GetProperties(ByVal attributes() As System.Attribute) _
As PropertyDescriptorCollection _
Implements ICustomTypeDescriptor.GetProperties
Dim props(Count) As PropertyDescriptor
Dim i As Int32
For i = 0 To Count - 1
props(i) = New XPropDescriptor(Item(i), attributes)
Next
Return New PropertyDescriptorCollection(props)
End Function
Public Function GetPropertyOwner(ByVal pd As PropertyDescriptor) _
As Object _
Implements ICustomTypeDescriptor.GetPropertyOwner
Return Me
End Function
#End Region
Public Overrides Function ToString() As String
Dim sbld As StringBuilder = New StringBuilder
Dim i As Int32
For i = 0 To Count - 1
sbld.Append("[" & i & "] " & Item(i).ToString & vbNewLine)
Next
Return sbld.ToString
End Function
End Class
Although this code is lengthy, it is not difficult to read it.
Most icustomtypedescriptor implementations are implemented by members in typedescriptor. Only
Getproperties is written separately. This part is also very simple, that is, the content in the collection is
Propertydescriptor collection, which is used to form the propertydescriptorcollection and return.
It should be noted that you can also use dictionary or other types of collection to form this class. The difference is that the getproperties method is different.
The remaining part is the overrides of tostring to facilitate the display of the content of the entire class. This program uses stringbuilder, which belongs to system. Text. When many strings are combined, this is much faster than using the operator.
Interface code
Add the following code to the xpgridwin. VB file.
Public Class XPGridWin
Private XProps As XProps = New XProps
Private Sub XPGridWin_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
PGrid.SelectedObject = XProps
End Sub
Private Sub CmdAdd_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles CmdAdd.Click
Dim xprop As XProp = New XProp
xprop.Name = TxtName.Text
xprop.Value = TxtValue.Text
XProps.Add(xprop)
PGrid.Refresh()
End Sub
Private Sub CmdShow_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles CmdShow.Click
TxtShow.Text = XProps.ToString
End Sub
End Class
This Code contains the following content.
- Define a private Global Object xprops and create an object when defining it;
- Associate this object with propertygrid during form. Load;
- Create an xprop object, assign the value of name and value to the xprops, and refresh the propertygrid;
- When you click cmdshow, The xprops content is displayed in the text box at the bottom of the form.
Test
- Enter data in name and value, and click Add. The content will be added to propertygrid;
- Modify some property values in propertygrid. After you click show, the modified values are stored in the custom collection.
XProps Extension
You can add several members to xprops to expand the xprops capability. For example, add loadfromxml and savetoxml to implement
Add loadfromdb and savetodb for the database and propertygrid.
. I won't go into details about this. I believe these are not difficult for you.