Search code examples
vb.netwinformsdatagridviewpropertiespropertygrid

Combining datagridview with propertygrid hiding duplicate values


I'm working on a small application that has a datagridview and propertygrid.

In this application there is a main object class and several derived classes from the main class.

So for example lets call the MainClass and DerivedClass

The datagridview is bound to a BindingList(Of MainClass) and when the user selects a cell or row the propertygird should display the DerivedClass properties

I can manage to do this, but because my MainClass has properties that are also available in the DerivedClass I have duplicate values, as I would only like to see the properties that are ONLY available in the DerivedClass.

How can I achieve this?

The solution could be this post, but sadly c# is total gibberish for me (I am not an experienced programmer..)

Public Class MainClass

    Public Property ComponentType As BodyComponentTypeEnum
    Public Enum BodyComponentTypeEnum
        Cylinder
    End Enum

    Public Property Height As Double
    Public Property Thickness As Double
    Public Property Material As String
    Public Property Diameter As Double
    Public Property Mass As Double
End Class


Public Class DerivedClass

    Inherits MainClass

    Public Property Segments As Integer
    Public Property WeldOrientation As Double

End Class

Application Capture


Solution

  • One way to do this would be to use a TypeConverter to provide the properties and based on some condition only returns the child class properties. But the property grid includes a BrowsableAttributes property which allows you to tell it to display only those properties bearing the attribute and values passed.

    The linked answer uses a custom attribute, but you can use others. This will use the CategoryAttribute.

    Public Class Widget
        <Category("Main")>
        Public Property Name As String
        <Category("Main")>
        Public Property ItemType As String
    
        Public Property Length As Double
        ...
    
    Public Class SubWidget
        Inherits Widget
    
        <Category("SubWidget"), DisplayName("Weld Orientation")>
        Public Property WeldOrientation As Double
    

    To prevent a SubWidget object from displaying parent properties, tell the PropertyGrid to only display the properties where the Category is "SubWidget":

    ' target attribute array
    Dim attr = New Attribute() {New CategoryAttribute("SubWidget")}
    ' pass collection to propgrid control
    propGrid.BrowsableAttributes = New AttributeCollection(attr)
    

    enter image description here

    You pass a collection which means you can have multiple qualifiers - a property must have all if them to show. To use a custom attribute:

    <AttributeUsage(AttributeTargets.Property)>
    Public Class PropertyGridBrowsableAttribute
        Inherits Attribute
    
        Public Property Browsable As Boolean
        Public Sub New(b As Boolean)
            Browsable = b
        End Sub
    
    End Class
    ...
    <Category("SubWidget"), DisplayName("Weld Orientation"),
    PropertyGridBrowsable(True)>
    Public Property WeldOrientation As Double
    

    If there is a chain if these (a SubSubWidget and more) a simple Boolean is not enough unless you create multiple attributes so that only the properties from the 'last' item shows.