Back to Devexpress

How to: Edit Multiple Objects

windowsforms-8368-controls-and-libraries-property-grid-how-to-edit-properties-of-multiple-objects-in-a-single-propertygridcontrol.md

latest7.9 KB
Original Source

How to: Edit Multiple Objects

  • Nov 12, 2020
  • 3 minutes to read

This example handles the CustomPropertyDescriptors event to display and edit multiple objects’ properties in a single PropertyGridControl.

csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraVerticalGrid.Events;

namespace CutomProperties {
    public partial class Form1 : Form {
        List<PropertyDescriptor> propertyStore = new List<PropertyDescriptor>();
        public Form1() {
            InitializeComponent();
            propertyStore.Add(new CustomPropertyDescriptor(this, "Form's Size", "Size"));
            propertyStore.Add(new CustomPropertyDescriptor(this, "Form's Title", "Text"));
            propertyStore.Add(new CustomPropertyDescriptor(this.propertyGridControl1, "PropertyGridControl's RecordWidth", "RecordWidth"));
            propertyStore.Add(new CustomPropertyDescriptor(this.button1, "Button's Visibility", "Visible"));
            this.propertyGridControl1.SelectedObject = propertyStore;
        }

        void propertyGridControl1_CustomPropertyDescriptors(object sender, CustomPropertyDescriptorsEventArgs e) {
            if(e.Source == propertyStore) {
                PropertyDescriptorCollection rootProperties = new PropertyDescriptorCollection(null);
                foreach(PropertyDescriptor pd in propertyStore) {
                    rootProperties.Add(pd);
                }
                e.Properties = rootProperties;
            }
        }
    }
    class CustomPropertyDescriptor : PropertyDescriptor {
        string name;
        PropertyDescriptor sourcePropertyDescriptor;
        object source;

        public CustomPropertyDescriptor(object source, string name, string targetPath) : base(name, null) {
            this.name = name;
            this.source = source;
            this.sourcePropertyDescriptor = TypeDescriptor.GetProperties(source)[targetPath];
            if(SourcePropertyDescriptor == null)
                throw new Exception("Can't bind to the source with the " + targetPath + " property");
        }

        public override string Name { get { return name; } }
        public override Type ComponentType { get { return SourcePropertyDescriptor.ComponentType; } }
        public override bool IsReadOnly { get { return SourcePropertyDescriptor.IsReadOnly; } }
        public override Type PropertyType { get { return SourcePropertyDescriptor.PropertyType; } }

        PropertyDescriptor SourcePropertyDescriptor { get { return sourcePropertyDescriptor; } }
        object Source { get { return source; } }

        public override object GetValue(object component) {
            return SourcePropertyDescriptor.GetValue(Source);
        }
        public override bool CanResetValue(object component) {
            return SourcePropertyDescriptor.CanResetValue(Source);
        }
        public override void ResetValue(object component) {
            SourcePropertyDescriptor.ResetValue(Source);
        }
        public override void SetValue(object component, object value) {
            SourcePropertyDescriptor.SetValue(Source, value);
        }
        public override bool ShouldSerializeValue(object component) {
            return SourcePropertyDescriptor.ShouldSerializeValue(Source);
        }
    }
}
vb
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports DevExpress.XtraVerticalGrid.Events

Namespace CutomProperties
    Partial Public Class Form1
        Inherits Form
        Private propertyStore As New List(Of PropertyDescriptor)()
        Public Sub New()
            InitializeComponent()
            propertyStore.Add(New CustomPropertyDescriptor(Me, "Form's Size", "Size"))
            propertyStore.Add(New CustomPropertyDescriptor(Me, "Form's Title", "Text"))
            propertyStore.Add(New CustomPropertyDescriptor(Me.propertyGridControl1, "PropertyGridControl's RecordWidth", "RecordWidth"))
            propertyStore.Add(New CustomPropertyDescriptor(Me.button1, "Button's Visibility", "Visible"))
            Me.propertyGridControl1.SelectedObject = propertyStore
        End Sub

        Private Sub propertyGridControl1_CustomPropertyDescriptors(ByVal sender As Object, ByVal e As CustomPropertyDescriptorsEventArgs) Handles propertyGridControl1.CustomPropertyDescriptors
            If e.Source Is propertyStore Then
                Dim rootProperties As New PropertyDescriptorCollection(Nothing)
                For Each pd As PropertyDescriptor In propertyStore
                    rootProperties.Add(pd)
                Next pd
                e.Properties = rootProperties
            End If
        End Sub
    End Class
    Friend Class CustomPropertyDescriptor
        Inherits PropertyDescriptor
        Private name_Renamed As String
        Private sourcePropertyDescriptor_Renamed As PropertyDescriptor
        Private source_Renamed As Object

        Public Sub New(ByVal source As Object, ByVal name As String, ByVal targetPath As String)
            MyBase.New(name, Nothing)
            Me.name_Renamed = name
            Me.source_Renamed = source
            Me.sourcePropertyDescriptor_Renamed = TypeDescriptor.GetProperties(source)(targetPath)
            If SourcePropertyDescriptor Is Nothing Then
                Throw New Exception("Can't bind to the source with the " & targetPath & " property")
            End If
        End Sub

        Public Overrides ReadOnly Property Name() As String
            Get
                Return name_Renamed
            End Get
        End Property
        Public Overrides ReadOnly Property ComponentType() As Type
            Get
                Return SourcePropertyDescriptor.ComponentType
            End Get
        End Property
        Public Overrides ReadOnly Property IsReadOnly() As Boolean
            Get
                Return SourcePropertyDescriptor.IsReadOnly
            End Get
        End Property
        Public Overrides ReadOnly Property PropertyType() As Type
            Get
                Return SourcePropertyDescriptor.PropertyType
            End Get
        End Property

        Private ReadOnly Property SourcePropertyDescriptor() As PropertyDescriptor
            Get
                Return sourcePropertyDescriptor_Renamed
            End Get
        End Property
        Private ReadOnly Property Source() As Object
            Get
                Return source_Renamed
            End Get
        End Property

        Public Overrides Function GetValue(ByVal component As Object) As Object
            Return SourcePropertyDescriptor.GetValue(Source)
        End Function
        Public Overrides Function CanResetValue(ByVal component As Object) As Boolean
            Return SourcePropertyDescriptor.CanResetValue(Source)
        End Function
        Public Overrides Sub ResetValue(ByVal component As Object)
            SourcePropertyDescriptor.ResetValue(Source)
        End Sub
        Public Overrides Sub SetValue(ByVal component As Object, ByVal value As Object)
            SourcePropertyDescriptor.SetValue(Source, value)
        End Sub
        Public Overrides Function ShouldSerializeValue(ByVal component As Object) As Boolean
            Return SourcePropertyDescriptor.ShouldSerializeValue(Source)
        End Function
    End Class
End Namespace

See Also

CustomPropertyDescriptors