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。 PropertyGridStringCollectionEditor 都用于编辑 现有的 属性值。通过不初始化 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