簡體   English   中英

具有自定義排序的WPF Propertygrid

[英]WPF Propertygrid with custom sorting

我正在為我的WPF項目尋找一個PropertyGrid,它允許我自定義列出屬性/類別的順序。 現在,我正在使用帶有CustomPropertyDescriptorExtended WPF Toolkit (社區版)PropertyGrid。 我的研究表明,使用PropertyGrid進行自定義排序是不可能的。

有(最好是免費的)解決方案嗎?

可以通過使用PropertyOrderAttribute屬性裝飾屬性來實現Extended WPF Toolkit中屬性的排序。

如果您不想在設計時通過用屬性裝飾POCO來污染POCO,或者順序在某種程度上是動態的,則可以在運行時通過創建類型轉換器並重寫GetProperties方法來添加屬性。 例如,如果您希望維護通用IList類型的索引順序:

using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
using System.ComponentModel;

 public class MyExpandableIListConverter<T> : ExpandableObjectConverter
{
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
    {
        if (value is IList<T>)
        {
            IList<T> list = value as IList<T>; 
            PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null);
            IEnumerator enumerator = list.GetEnumerator();
            int counter = -1;
            while (enumerator.MoveNext())
            {
                counter++;
                propDescriptions.Add(new ListItemPropertyDescriptor<T>(list, counter));

            }
            return propDescriptions;
        }
        else
        {
            return base.GetProperties(context, value, attributes);
        }
    }        
}

使用ListItemPropertyDescriptor定義如下:

using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
using System.ComponentModel;

public class ListItemPropertyDescriptor<T> : PropertyDescriptor
{
    private readonly IList<T> owner;
    private readonly int index;

    public ListItemPropertyDescriptor(IList<T> owner, int index) : base("["+ index+"]", null)
    {
        this.owner = owner;
        this.index = index;

    }

    public override AttributeCollection Attributes
    {
        get
        {
            var attributes = TypeDescriptor.GetAttributes(GetValue(null), false);
            //If the Xceed expandable object attribute is not applied then apply it
            if (!attributes.OfType<ExpandableObjectAttribute>().Any())
            {
                attributes = AddAttribute(new ExpandableObjectAttribute(), attributes);
            }

            //set the xceed order attribute
            attributes = AddAttribute(new PropertyOrderAttribute(index), attributes);

            return attributes;
        }
    }
    private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes)
    {
        Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1];
        oldAttributes.CopyTo(newAttributes, 1);
        newAttributes[0] = newAttribute;

        return new AttributeCollection(newAttributes);
    }

    public override bool CanResetValue(object component)
    {
        return false;
    }

    public override object GetValue(object component)
    {
        return Value;
    }

    private T Value
      => owner[index];

    public override void ResetValue(object component)
    {
        throw new NotImplementedException();
    }

    public override void SetValue(object component, object value)
    {
        owner[index] = (T)value;
    }

    public override bool ShouldSerializeValue(object component)
    {
        return false;
    }

    public override Type ComponentType
      => owner.GetType();

    public override bool IsReadOnly
      => false;

    public override Type PropertyType
      => Value?.GetType();

}

此代碼的部分改編自以下SO答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM