PropertyGrid for WPF
入れ子のプロパティ

PropertyGrid allows you to show nested properties by creating a nested property editor. It lets you create a nested property editor with the help of  IPropertyGridEditor interface as described in Custom Editors. The following image displays a nested editor to show nested properties.

PropertyGrid with nested editor showing nested properties

To create a nested property editor, create a class that implements the IPropertyGridEditor interface and add an instance of this class to the AvailableEditors collection on the PropertyGrid control as shown in the following code.

C#
コードのコピー
    public partial class NestedProperties : Window
    {
        public NestedProperties()
        {
            InitializeComponent();

            Tag = Properties.Resources.PropertyGridNestedPropertiesDesc;

            var nestedPropertyEditor = new NestedPropertyEditor();

            // NestedPropertyEditor でサポートされるタイプを追加します
            nestedPropertyEditor.SupportedTypes.AddRange(new Type[]
             {
               typeof(Owner),
               typeof(Sales)
             });

            // カスタムのネストされたプロパティエディタを C1PropertyGrid の利用可能なエディタに追加します
            propertyGrid.AvailableEditors.Add(nestedPropertyEditor);
            InitPropertyGrid();
        }
        private void InitPropertyGrid()
        {
            propertyGrid.SelectedObject = new Company()
            {
                RegistrationId = "19083",
                CompanyName = "Microsoft",
                Owner = new Owner()
                {
                    Name = "Bill Gates",
                    Gender = "Male",
                    Contact = "+1 983-234-122"
                },
                Sales = new Sales()
                {
                    UnitsSold = 2390000,
                    Revenue = 109000000,
                    Loss = 900000
                },
                Departments = new List<Department>()
                {
                    new Department()
                    {
                        Id = "1",
                        DepartmentName = "Manufacturing",
                        EmployeeCount = 902
                    },
                    new Department()
                    {
                        Id = "2",
                        DepartmentName = "Development",
                        EmployeeCount = 150
                    },
                    new Department()
                    {
                        Id = "3",
                        DepartmentName = "Marketing",
                        EmployeeCount = 1250
                    }
                }

            };

        }
    }
}
public class NestedPropertyEditor : Expander, IPropertyGridEditor
{
    private C1PropertyGrid _propertyGrid;

    public event PropertyChangedEventHandler ValueChanged;

    /// <summary>
    /// このエディタでサポートするタイプ
    /// </summary>
    public List<Type> SupportedTypes { get; set; }

    public NestedPropertyEditor()
    {
        SupportedTypes = new List<Type>();
        _propertyGrid = new C1PropertyGrid();
        Content = _propertyGrid;
    }

    public void Attach(PropertyAttribute property)
    {
        Header = property.PropertyInfo.PropertyType.Name;

        // 内部 C1PropertyGrid の SelectedObject をネストされたプロパティに連結します
        Binding binding = new Binding(property.PropertyInfo.Name);
        binding.Source = property.SelectedObject;
        binding.Mode = BindingMode.TwoWay;
        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        BindingOperations.SetBinding(_propertyGrid, C1PropertyGrid.SelectedObjectProperty, binding);
    }

    public IPropertyGridEditor Create()
    {
        return new NestedPropertyEditor();
    }

    public void Detach(PropertyAttribute property)
    {
        _propertyGrid.SelectedObject = null;
    }

    public bool Supports(PropertyAttribute Property)
    {
        // プロパティタイプがこのエディタでサポートされているかどうかを確認します
        return SupportedTypes.Any(x => x == Property.PropertyInfo.PropertyType);
    }

    public bool Supports(PropertyInfo property)
    {
        throw new NotImplementedException();
    }

    public FrameworkElement Create(C1PropertyGrid parent)
    {
        throw new NotImplementedException();
    }

    public void Attach(FrameworkElement editor, PropertyGroup group, Action<FrameworkElement, object> valueChanged)
    {
        throw new NotImplementedException();
    }

    public void Detach(FrameworkElement editor)
    {
        throw new NotImplementedException();
    }

In the above example, PropertyGrid is bound to a class, Company, whose properties are displayed in the PropertyGrid control. The following code showcases the Company class and its properties.

C#
コードのコピー
public class Company
{
    public string RegistrationId { get; set; }
    public string CompanyName { get; set; }
    public Owner Owner { get; set; }
    public Sales Sales { get; set; }
    public List<Department> Departments { get; set; }
}

public class Department
{
    public string Id { get; set; }
    public string DepartmentName { get; set; }
    public int EmployeeCount { get; set; }
}

public class Sales
{
    public double UnitsSold { get; set; }
    public double Revenue { get; set; }
    public double Loss { get; set; }
}

public class Owner
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public string Contact { get; set; }
}