用户控件的Vb.Net设置属性 [英] Vb.Net setting properties of user control
问题描述
我有一个自定义用户控件 &我希望从设计器中设置它的一些属性.这些属性将来自一个结构.这是当前代码
I have a custom user control & I am looking to set some of its properties from the designer. The properties will be coming from a structure. Here is the current code
Private fooList As Foo_structure
Public Structure Foo_structure
Public Property a As Integer
Public Property b As Integer
Public Property c As Extras
End Structure
Public Structure Extras
Public Property precision As Integer
Public Property light As String
End Structure
Public Property foo As Foo_structure
Get
Return fooList
End Get
Set(ByVal value As Foo_structure)
fooList = value
End Set
End Property
我需要能够从设计器属性面板设置 Foo_structure 的属性,如下图所示.
I need to be able to set the properties of the Foo_structure from the designer properties panel like the eg shown in the image below.
推荐答案
您将需要一个 TypeConverter
将 foo 折叠为字符串;并从中转换回来.嵌套类型意味着您需要为 Extras
编写另一个.您可能需要使用一些属性来处理设计器持久性.
You are going to need a TypeConverter
to collapse foo into a string; and convert back from it. The nested Type means you need to write another one for Extras
. You will probably need to use some attributes to handle designer persistence.
开始,我觉得你至少需要把Foo_structure改成Class,否则没有办法给实例Extras
添加代码(也没有办法创建Foo实例).这应该可以帮助您入门(更改了一些名称):
To start, I think you need to change at least Foo_structure to a Class, otherwise there is no way to add code to instance Extras
(also no way to create a Foo instance). This should get you started (changed some names):
' Foo converted to Class:
<TypeConverter("FooItemConverter")>
Public Class FooBar
<DefaultValue(0)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
Public Property Foo As Integer
<DefaultValue(0)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
Public Property Bar As Integer
<EditorBrowsable(EditorBrowsableState.Always)>
<NotifyParentProperty(True)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property Ex As Extras
Public Sub New(a1 As Integer, b2 As Integer)
Foo = a1
Bar = b2
Ex = New Extras ' do not want NOTHING flying about
End Sub
End Class
DefaultValue
并没有像你想象的那样做.当当前值不等于默认值时,它会告诉 IDE 序列化属性的值.DesignerSerializationVisibility
告诉 VS 保存属性的值.Foo 和 Bar 都需要这些.
DefaultValue
does not do what you may think it does. It tells the IDE to serialize the value for a property when the current value does not equal the Default. DesignerSerializationVisibility
tells VS to save the value for a property. Foo and Bar both need these.
Ex/Extra 是不同的.NotifyParentProperty
允许在 Extra 属性值更改时通知 FooBar,因此 IDE 窗口被更新,内部DirtyFlag"设置等;DesignerSerializationVisibility.Content
告诉 VS 我们知道我们不能将 Ex 保存为值,所以保存内容.
Ex/Extra is different. NotifyParentProperty
allows FooBar to be notified when a Extra property value has changed so the IDE window is updated, internal "DirtyFlag" set etc; DesignerSerializationVisibility.Content
tells VS that we know we cant save Ex as a value, so save the contents.
然后是 FooItemConverter.这将是在 Props 窗口中显示您想要的字符串并从该字符串创建一个 Foo 项目的东西:
Then comes the FooItemConverter. This will be the thing that displays the string you want in the Props window AND creates a Foo item from that string:
Friend Class FooItemConverter
Inherits ExpandableObjectConverter
' tells the IDE what conversions it can handle:
Public Overrides Function CanConvertTo(context As ITypeDescriptorContext,
destType As Type) As Boolean
If destType = GetType(String) Then
' Yes I Can
Return True
End If
' Probably have to also say YES to an InstanceDescriptor
Return MyBase.CanConvertTo(context, destType)
End Function
之后,使用 ConvertTo
函数将 foo 转换为字符串.像这样:
After that a ConvertTo
function is used to convert foo to a string. Something like this:
Public Overrides Function ConvertTo(context As ITypeDescriptorContext,
culture As Globalization.CultureInfo,
value As Object, destType As Type) As Object
If destType = GetType(String) Then
Dim f As FooBar = CType(value, FooBar)
Return String.Format("{0}, {1}, {2}",
f.foo.ToString,
f.bar.ToString,
f.Ex.ToString)
' outputs: X, Y, <ex>
' where Ex is what we use in the ExtraItemConverter
End If
Return MyBase.ConvertTo(context, destType)
End Function
如果ExtraItemConverter.ConvertTo
使用"({0}/{1})"
格式,则控件内容将显示为:F, B, (P/L)
其中 F=Foo, B=Bar 等
If ExtraItemConverter.ConvertTo
use a format of "({0} / {1})"
then the control contents will show as: F, B, (P / L)
where F=Foo, B=Bar etc.
要让它工作,你需要 4 个程序:CanConvertTo、ConvertTo、CanConvertFrom、ConvertFrom 都响应字符串.您可能将能够仅使用
属性来实现持久性.
To make it work, you need 4 procedures: CanConvertTo, ConvertTo, CanConvertFrom, ConvertFrom all responding to string. You probably will be able to just use the <DefaultValue>
attribute for persistence.
FooItemConverter.ConvertFrom
必须知道如何从该字符串创建对象.通常,这是这样做的:
FooItemConverter.ConvertFrom
will have to know how to create an object from that string. Normally, that is done like this:
' parse the string you made and create a Foo
Dim els As String() = str.Split(","c)
Return New myFoo(Convert.ToInt32(els(0)), Convert.ToInt32(els(1)))
请注意,第三个元素被忽略,因为这实际上是由 ExtraItemConverter
处理的.该转换器将非常相似.
Note that the 3rd element is ignored as that is actually for the ExtraItemConverter
to handle. That converter would be very similar.
因此,您首先必须决定是坚持结构还是使用类(类的另一个优点是您找到的 99.999% 的示例都基于类).这些人知道很多关于TypeConverters
.
So, you will first have to decide whether to cling to the structure or use a class (another pro for a Class is that 99.999% of the examples you find will be Class based). These guys know a lot about TypeConverters
.
这篇关于用户控件的Vb.Net设置属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!