PropertyGrid 不更新字符串列表
PropertyGrid Not Updating List of String
我在 PropertyGrid
.
上遇到了一些麻烦
我已将所选对象设置为包含各种属性的 class,其中 90% 的属性都可以正常工作,但对于任何 属性 是 List(Of String)
的地方,它都不会出现调用 属性.
的 Set
部分
我手上的class如下(缩略版):
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
设置为 class:
Dim _Properties As Object
_Properties = New VideosProperties
PropertyGrid1.SelectedObject = _Properties
我已经使用以下代码初始化了列表:
Extensions = New List(Of String)
当我 运行 我的代码时,PropertyGrid
显示 EpisodeColorOdd
属性 并且它工作正常,但扩展 属性 没有。
当您使用 PropertyGrid
编辑扩展 属性 时,它不会调用 属性 的 Set(value as List(Of String))
部分。
我环顾四周,似乎找不到解决方案(我可能还不够努力)。
有人能帮忙吗?
编辑
Plutonix - 您的代码无效。我已经复制并粘贴到一个新项目中,但出现错误。
我在
处收到错误
<Editor("System.Windows.Forms...etc")>
告诉我 "Type 'Editor' is not defined",所以我导入了 "System.ComponentModel",现在得到
在同一点说 "Overload resolution failed because no accessible 'New' accepts this number of arguments." 的错误。
如果我删除该部分,它将无法正常工作。
我 运行 代码,表格打开,我点击食物 属性 并打开一个编辑器,我点击添加并得到我遇到的错误 "Constructor on type 'System.String' not found."前,
我用
修复了
<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")>
但是现在,当我单击 属性 时,它会弹出一个不同的编辑器并且实际上不会访问 属性 的设置部分。所以,我回到原点。
我不能确定,但是从显示的代码来看,您没有初始化 collection。 PropertyGrid
和 StringCollectionEditor
都用于编辑 现有的 属性值。通过不初始化 List
- 它本身是一个 object - 属性 容器不存在并且它们都不会为您创建它。
您的代码显示了 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
.
如果 当您将 object 发送到 PropertyGrid
[=68] 时,您的 object 有一个有效的 List
实例=]and 指定了一个有效的编辑器,您将看到:
PropGrid 将显示 "Collection" 表示它知道它是什么,而“...”表示 PropGrid 有一个与之关联的有效编辑器。证明它保留了 collection:
lbFoods.Items.AddRange(A.Foods.ToArray)
' results in:
请注意,我在 Foods
的 setter 中没有任何内容,但它有效。 Collection 编辑通常不会通过 setter 将 collection 项 大量 传回。相反,他们使用 Add
and/or AddRange
的方法 collection。
因此,我可以省略 setter,这也可以防止某些代码将 List
设置回 Nothing
。当然,代码可以将字符串项更改为其他内容或重新排序,这也可能是错误的。
为避免这种情况,您可能需要使用实现 List(of T)
或 Collection(Of T)
的 Collection Class。通过这种方式,您的代码可以提供对项目的访问、限制可以执行的操作,甚至验证添加的项目。
有关更多提示和信息,请参阅 Guidelines for Collections。
我在 PropertyGrid
.
我已将所选对象设置为包含各种属性的 class,其中 90% 的属性都可以正常工作,但对于任何 属性 是 List(Of String)
的地方,它都不会出现调用 属性.
Set
部分
我手上的class如下(缩略版):
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
设置为 class:
Dim _Properties As Object
_Properties = New VideosProperties
PropertyGrid1.SelectedObject = _Properties
我已经使用以下代码初始化了列表:
Extensions = New List(Of String)
当我 运行 我的代码时,PropertyGrid
显示 EpisodeColorOdd
属性 并且它工作正常,但扩展 属性 没有。
当您使用 PropertyGrid
编辑扩展 属性 时,它不会调用 属性 的 Set(value as List(Of String))
部分。
我环顾四周,似乎找不到解决方案(我可能还不够努力)。
有人能帮忙吗?
编辑
Plutonix - 您的代码无效。我已经复制并粘贴到一个新项目中,但出现错误。
我在
<Editor("System.Windows.Forms...etc")>
告诉我 "Type 'Editor' is not defined",所以我导入了 "System.ComponentModel",现在得到 在同一点说 "Overload resolution failed because no accessible 'New' accepts this number of arguments." 的错误。
如果我删除该部分,它将无法正常工作。
我 运行 代码,表格打开,我点击食物 属性 并打开一个编辑器,我点击添加并得到我遇到的错误 "Constructor on type 'System.String' not found."前, 我用
修复了<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")>
但是现在,当我单击 属性 时,它会弹出一个不同的编辑器并且实际上不会访问 属性 的设置部分。所以,我回到原点。
我不能确定,但是从显示的代码来看,您没有初始化 collection。 PropertyGrid
和 StringCollectionEditor
都用于编辑 现有的 属性值。通过不初始化 List
- 它本身是一个 object - 属性 容器不存在并且它们都不会为您创建它。
您的代码显示了 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
.
如果 当您将 object 发送到 PropertyGrid
[=68] 时,您的 object 有一个有效的 List
实例=]and 指定了一个有效的编辑器,您将看到:
PropGrid 将显示 "Collection" 表示它知道它是什么,而“...”表示 PropGrid 有一个与之关联的有效编辑器。证明它保留了 collection:
lbFoods.Items.AddRange(A.Foods.ToArray)
' results in:
请注意,我在 Foods
的 setter 中没有任何内容,但它有效。 Collection 编辑通常不会通过 setter 将 collection 项 大量 传回。相反,他们使用 Add
and/or AddRange
的方法 collection。
因此,我可以省略 setter,这也可以防止某些代码将 List
设置回 Nothing
。当然,代码可以将字符串项更改为其他内容或重新排序,这也可能是错误的。
为避免这种情况,您可能需要使用实现 List(of T)
或 Collection(Of T)
的 Collection Class。通过这种方式,您的代码可以提供对项目的访问、限制可以执行的操作,甚至验证添加的项目。
有关更多提示和信息,请参阅 Guidelines for Collections。