Сетка свойств .Net.Есть ли способ позволить сетке манипулировать объектом по-другому?

StackOverflow https://stackoverflow.com/questions/931644

Вопрос

Как я понял, сетке свойств предоставляется объект, которым она может манипулировать, извлекая его свойства с помощью отражений.

Моя проблема в том, что у меня есть набор параметров, который определяется во время выполнения, поэтому я не могу статически составить класс со свойствами для представления этого набора.

У меня есть две идеи для решения этой проблемы, но обе они сложны и, вероятно, отнимут много времени, на самом деле я скажу, что они непрактичны в моих временных ограничениях.Один из них — использовать Reflection Emit для динамического определения класса, а другой — динамически создать исходный файл C# и затем скомпилировать его с помощью CodeDom.

Может ли сетка свойств вести себя по-другому (кроме извлечения свойств объекта с использованием отражений), что может решить мою проблему?

Если нет, знаете ли вы какой-либо другой элемент управления, который может выполнить эту работу за меня?

Я хочу сказать, что причина, по которой я с самого начала обратился к сетке свойств, заключалась в ее способности предоставлять действительно приятный пользовательский интерфейс извлечения данных для распространенных типов. Для цвета вы автоматически получаете палитру, для dataTime у вас автоматически есть хороший календарь.Я бы хотел получить эти вещи автоматически, если это возможно.

Это было полезно?

Решение

Да, PropertyGrid может отображать вещи другой чем просто свойства времени компиляции, используя любое из TypeConverter, ICustomTypeDescriptor или TypeDescriptionProvider для предоставления псевдосвойств времени выполнения.Можете ли вы привести пример того, как выглядят ваши параметры?Я должен был бы привести пример...


вот базовый пример (все есть string, и т. д.) на основе более ранний ответ (связанные, но разные):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
class PropertyBagPropertyDescriptor : PropertyDescriptor {
    public PropertyBagPropertyDescriptor(string name) : base(name, null) { }
    public override object GetValue(object component) {
        return ((PropertyBag)component)[Name];
    }
    public override void SetValue(object component, object value) {
        ((PropertyBag)component)[Name] = (string)value;
    }
    public override void ResetValue(object component) {
        ((PropertyBag)component)[Name] = null;
    }
    public override bool CanResetValue(object component) {
        return true;
    }
    public override bool ShouldSerializeValue(object component)
    { // *** this controls whether it appears bold or not; you could compare
      // *** to a default value, or the last saved value...
        return ((PropertyBag)component)[Name] != null;
    }
    public override Type PropertyType {
        get { return typeof(string); }
    }
    public override bool IsReadOnly {
        get { return false; }
    }
    public override Type ComponentType {
        get { return typeof(PropertyBag); }
    }
}
[TypeConverter(typeof(PropertyBagConverter))]
class PropertyBag {
    public string[] GetKeys() {
        string[] keys = new string[values.Keys.Count];
        values.Keys.CopyTo(keys, 0);
        Array.Sort(keys);
        return keys;
    }
    private readonly Dictionary<string, string> values
        = new Dictionary<string, string>();
    public string this[string key] {
        get {
            string value;
            values.TryGetValue(key, out value);
            return value;
        }
        set {
            if (value == null) values.Remove(key);
            else values[key] = value;
        }
    }
}
// has the job of (among other things) providing properties to the PropertyGrid
class PropertyBagConverter : TypeConverter {
    public override bool GetPropertiesSupported(ITypeDescriptorContext context) {
        return true; // are we providing custom properties from here?
    }
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, System.Attribute[] attributes) {
        // get the pseudo-properties
        PropertyBag bag = (PropertyBag)value;
        string[] keys = bag.GetKeys();
        PropertyDescriptor[] props = Array.ConvertAll(
            keys, key => new PropertyBagPropertyDescriptor(key));
        return new PropertyDescriptorCollection(props, true);
    }
}

static class Program {
    [STAThread]
    static void Main() { // demo form app
        PropertyBag bag = new PropertyBag();
        bag["abc"] = "def";
        bag["ghi"] = "jkl";
        bag["mno"] = "pqr";
        Application.EnableVisualStyles();
        Application.Run(
            new Form {
                Controls = { new PropertyGrid {
                    Dock = DockStyle.Fill,
                    SelectedObject = bag
                }}
            });
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top