简体   繁体   English

PropertyGrid不更新字符串列表

[英]PropertyGrid Not Updating List of String

I'm having a little trouble with a PropertyGrid . 我在使用PropertyGrid遇到了一些麻烦。

I have set the selected object to a class containing various properties and 90% of them work correctly but for any where the property is a List(Of String) it doesn't appear to call the Set part of the property. 我已经将选定的对象设置为包含各种属性的类,并且其中90%可以正常工作,但是对于该属性为List(Of String)任何属性,它似乎都没有调用该属性的Set部分。

The class I have is as follows (shortened version): 我的班级如下(简化版):

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

I have set the SelectedObject to be this class using the following code: 我使用以下代码将SelectedObject设置为此类:

Dim _Properties As Object

_Properties = New VideosProperties

PropertyGrid1.SelectedObject = _Properties

I have Initialized the List using the following code: 我已经使用以下代码初始化了列表:

Extensions = New List(Of String)

When I run my code, the PropertyGrid shows the EpisodeColorOdd property and this works correctly, but the Extensions property doesn't. 当我运行代码时, PropertyGrid显示EpisodeColorOdd属性,并且此属性可以正常运行,但是Extensions属性却不能。

When you edit the Extensions property using the PropertyGrid , it doesn't call the Set(value as List(Of String)) part of the property. 使用PropertyGrid编辑扩展属性时,它不会调用PropertyGridSet(value as List(Of String))部分。

I've had a look around and can't seem to find a solution (I'm probably not looking hard enough). 我四处张望,似乎找不到解决方法(我可能看起来不够努力)。

Can anyone help? 有人可以帮忙吗?

EDIT 编辑

Plutonix - Your code doesn't work. Plutonix-您的代码无效。 I have already copied and pasted into a new project and I get errors. 我已经复制并粘贴到一个新项目中,但出现错误。
I get an error at 我在遇到错误

<Editor("System.Windows.Forms...etc")> 

telling me "Type 'Editor' is not defined", so I Imported "System.ComponentModel" and now get an error saying "Overload resolution failed because no accessible 'New' accepts this number of arguments." 告诉我“未定义类型'Editor'”,因此我导入了“ System.ComponentModel”,现在收到一条错误消息,“过载解析失败,因为没有可访问的'New'接受此数量的参数。” at the same point. 在同一时间。

If I remove the that part it doesn't work correctly. 如果我删除了那部分,它将无法正常工作。

I run the code, the form opens, I click on the Foods property and an Editor opens, I click Add and get the error "Constructor on type 'System.String' not found." 我运行代码,打开表单,单击Foods属性,然后打开编辑器,单击“添加”,并显示错误“找不到类型'System.String'的构造函数”。 which I've had before, and I fixed using 我以前有过,我固定使用

<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")> 

instead of 代替

<Editor("System.Windows.Forms...etc")>

Now though, when I click on the property, it brings up a different editor and doesn't actually access the Set part of the property. 现在,当我单击该属性时,它会显示一个不同的编辑器,并且实际上并没有访问该属性的Set部分。 So, I'm back to square one. 所以,我回到正题。

I cant be sure but from the code shown, you dont initialize the collection. 我不能确定,但​​是从显示的代码中,您不会初始化集合。 Both the PropertyGrid and StringCollectionEditor are intended to edit existing properties values. PropertyGridStringCollectionEditor均旨在编辑现有属性值。 By not initializing the List - which itself is an object - that property container does not exist and neither of them will create it for you. 通过不初始化本身就是对象的List ,该属性容器将不存在,并且它们都不为您创建它。

Your code shows the getter/setter boilerplate, but nothing about the backing fields. 您的代码显示了getter / setter样板,但没有任何有关后备字段的信息。

Also, since VideosProperties is a Type, you should use it to declare your variable as that Type rather than As Object . 另外,由于VideosProperties是Type,因此应使用它来将变量声明为Type而不是As Object By doing that, you are casting the var to the lowest possible form; 这样,您将var转换为尽可能低的形式。 your properties are only available via late binding which requires Option Strict off. 您的属性只能通过后期绑定使用,这需要Option Strict禁用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

The key is that in the constructor ( Sub New ) you create the list instance to hold the food items, video extensions or whatever. 关键是在构造函数( Sub New )中,您创建列表实例以容纳食品,视频扩展名或其他内容。 Using it: 使用它:

' 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

After the edit, A.Foods will contain whatever was entered via the StringCollectionEditor . 编辑后, A.Foods将包含通过StringCollectionEditor输入的任何内容。 If A is declared As Object , the code line to set the Weight will prevent the code from compiling (with Option Strict on). 如果A声明As Object ,则设置权Weight的代码行将阻止代码编译(启用Option Strict时)。 This is because System.Object does not have a Weight property. 这是因为System.Object没有Weight属性。 A As Animal allows the compiler to see and use the properties defined. A As Animal ,编译器可以查看和使用定义的属性。 I suspect you are not using Option Strict . 我怀疑您没有使用Option Strict

If your object has a valid List instance when you send your object to the PropertyGrid and a valid Editor is specified, you'll see this: 如果将对象发送到PropertyGrid时对象具有有效的List实例, 并且指定了有效的Editor,则将看到以下内容:

在此处输入图片说明

The PropGrid will display "Collection" indicating it knows what it is, and the "..." indicates the PropGrid has a valid editor associated with it. PropGrid将显示“集合”,表明它知道它是什么,而“ ...”表明PropGrid具有与其关联的有效编辑器。 Proof that it retains the collection: 证明它保留了集合:

lbFoods.Items.AddRange(A.Foods.ToArray)
' results in:

在此处输入图片说明 在此处输入图片说明


Note that I have nothing in the setter for Foods , yet it works. 请注意,我对Foods的设置没有任何要求,但是它可以工作。 Collection Editors do not usually pass collection items back en masse via the setter. 收集编辑通常不经传的setter集合项回到集体 Instead, they use the Add and/or AddRange method of the collection. 而是使用集合的Add和/或AddRange方法。

So, I can omit the setter which also prevents some piece of code from setting the List back to Nothing . 因此,我可以省略setter,它也可以防止某些代码将List设置回Nothing Of course, code can change the string items to something else or re order them which also might be bad. 当然,代码可以将字符串项更改为其他内容或重新排序它们,这可能也很不好。

To avoid this, you might want to use a Collection Class which implements List(of T) or Collection(Of T) . 为了避免这种情况,您可能想要使用实现List(of T)Collection(Of T)的Collection类。 This way your code can provide access to items, limit what can be done, and even validate items added. 这样,您的代码就可以提供对项目的访问权限,限制可以完成的操作,甚至可以验证添加的项目。

See Guidelines for Collections for more tips and information. 有关更多提示和信息,请参阅收集指南

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM