我对PropertyGrid
感到有点麻烦。
我已将所选对象设置为包含各种属性的类,其中90%正常工作,但对于属性为List(Of String)
的任何属性,它似乎不会调用Set
该物业的一部分。
我的课程如下(缩短版):
Public Class VideosProperties
Public Property EpisodeColorOdd As Color
Get
Return Videos_EpisodeColorOdd
End Get
Set(value As Color)
Videos_EpisodeColorOdd = value
End Set
End Property
<Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"System.Drawing.Design.UITypeEditor,System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")>
Public Property Extensions As List(Of String)
Get
Return Videos_Extensions
End Get
Set(value As List(Of String))
Videos_Extensions = value
End Set
End Property
End Class
我已使用以下代码将SelectedObject
设置为此类:
Dim _Properties As Object
_Properties = New VideosProperties
PropertyGrid1.SelectedObject = _Properties
我使用以下代码初始化了List:
Extensions = New List(Of String)
当我运行我的代码时,PropertyGrid
会显示EpisodeColorOdd
属性,这样可以正常工作,但Extensions属性不会。
使用PropertyGrid
编辑扩展程序属性时,它不会调用属性的Set(value as List(Of String))
部分。
我已经环顾四周,似乎无法找到解决方案(我可能看起来不够努力)。
有人可以帮忙吗?
修改
Plutonix - 您的代码不起作用。我已经复制并粘贴到一个新项目中,我收到了错误
我收到错误<Editor("System.Windows.Forms...etc")>
告诉我&#34;输入&#39;编辑&#39;没有定义&#34;,所以我导入了&#34; System.ComponentModel&#34;现在得到 错误说&#34;重载决议失败,因为没有可访问的&#39;新&#39;接受这个数量的论点。&#34;在同一点上。
如果删除该部分,则无法正常工作。
我运行代码,打开表单,单击Foods属性并打开编辑器,单击Add并获取错误&#34;构造函数类型&#39; System.String&#39;没找到。&#34;我之前有过的, 我使用
修复了<Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor,System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")>
而不是
<Editor("System.Windows.Forms...etc")>
现在,当我点击该属性时,它会显示一个不同的编辑器,并且实际上并没有访问该属性的Set部分。所以,我回到原点。
答案 0 :(得分:2)
我无法确定但是从显示的代码中,您不会初始化集合。 PropertyGrid
和StringCollectionEditor
都旨在编辑现有的属性值。通过不初始化List
- 它本身就是一个对象 - 该属性容器不存在,并且它们都不会为您创建它。
您的代码显示了getter / setter样板,但没有关于支持字段的信息。
此外,由于VideosProperties
是一个类型,因此您应该使用它将变量声明为该类型,而不是As Object
。通过这样做,您将var转换为尽可能低的形式;您的属性仅适用于需要Option Strict
关闭的后期绑定。
Public Class Animal
' auto implement props available since VS2010:
Public Property Name As String
Public Property Species As String
Public Property Weight As Double
Public Property Coloring As Color
' backing field for the List:
Private mFoods As List(Of String)
' this of course would be the same as your code...
' no need to repeat
<Editor("System.Windows.Forms...etc")>
Public Property Foods As List(Of String)
Get
Return mFoods
End Get
Set(value As List(Of String))
' see notes
End Set
End Property
Public Sub New(n As String, s As String)
Name = n
Species = s
' initialize the List instance:
mFoods = New List(Of String)
End Sub
End Class
关键是在构造函数(Sub New
)中创建列表实例以保存食物项目,视频扩展或其他任何内容。使用它:
' class/form level variable declared as Animal NOT Object
Private A As Animal
...
A = New Animal("Ziggy", "Feline")
A.Weight = 12.4 ' not possible if A is As Object
pGrid.SelectedObject = A
编辑完成后,A.Foods
将包含通过StringCollectionEditor
输入的内容。如果A
被声明为As Object
,则设置Weight
的代码行将阻止代码编译(启用Option Strict
)。这是因为System.Object
没有Weight
属性。 A As Animal
允许编译器查看和使用定义的属性。我怀疑你没有使用Option Strict
。
List
并且指定了有效的编辑器时 您的对象有一个有效的PropertyGrid
实例,您就是&# 39;我会看到这个:
PropGrid将显示&#34; Collection&#34;表明它知道它是什么,以及&#34; ...&#34;表示PropGrid具有与之关联的有效编辑器。证明它保留了该集合:
lbFoods.Items.AddRange(A.Foods.ToArray)
' results in:
请注意,我在Foods
的setter中没有任何内容,但它确实有效。集合编辑器通常不会通过setter将集合项目传回 en masse 。相反,他们使用集合的Add
和/或AddRange
方法。
所以,我可以省略setter,这也会阻止某些代码将List
设置回Nothing
。当然,代码可以将字符串项更改为其他内容或重新排序它们也可能是坏的。
为避免这种情况,您可能希望使用实现List(of T)
或Collection(Of T)
的Collection类。这样,您的代码可以提供对项目的访问,限制可以执行的操作,甚至验证添加的项目。
有关更多提示和信息,请参阅Guidelines for Collections。