.Net 属性网格。 有没有办法让网格以不同的方式操作对象

发布于 2024-07-22 05:11:38 字数 434 浏览 7 评论 0原文

据我了解,属性网格被赋予一个对象,它可以通过使用反射提取其属性来操作该对象。

我的问题是我有一组在运行时确定的参数,因此我无法静态地组成一个具有属性的类来表示这组参数。

我有两个想法来解决这个问题,但这两个想法都很复杂,并且可能会消耗大量时间,事实上,我会说它们在我的时间限制下不切实际。 一种是使用 Reflection Emit 动态定义类,另一种是动态构建 C# 源文件,然后使用 CodeDom 编译它。

属性网格是否可以以不同的方式运行(除了使用反射提取对象的属性之外)来满足我的问题?

如果没有,您知道还有其他控件可以帮我完成这项工作吗?

我想说,我从一开始就使用属性网格的原因是它能够为常见类型提供非常好的数据检索 UI。对于颜色,您会自动获得调色板,对于数据时间,您会自动拥有一个不错的日历。 如果可能的话,我想自动获取这些东西。

As I understood , The property grid is given an object which it can manipulate by extracting its Properties using reflections.

My problem is that I have a set of Parameters that is determined during run-time , thus I can't staticly compose a class with properties to represent this set.

I have two idea in mind to solve this problem but both are complex and will probably consume lot of time , infact i will say they are not practical under my time constraints. One is to use Reflection Emit in order to define a class dynamically and the other is to dynamiclly build a C# source file and then compile it using CodeDom.

Can Property grid behave in a different manner( other then extracting the Properties of an object using reflections ) that can suite my problem?

If no do you know any other control that can do the job for me?

I want to say that the reason I went to the property grid from the begining was its ability to provide realy nice Data Retrieval UI for common types.For color you autometically get a palette , For dataTime you automatically have a nice calender. I would like to get those things automatically , If possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

匿名的好友 2024-07-29 05:11:38

是的,通过使用 TypeConverterICustomTypeDescriptor 中的任何一个,PropertyGrid 可以显示除编译时属性之外的内容。或 TypeDescriptionProvider 提供运行时伪属性。 你能举例说明你的参数是什么样的吗? 我应该能够提供一个示例...


这是一个基于 早期回复(相关但不同):

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
                }}
            });
    }
}

Yes, PropertyGrid can display things other than just the compile-time properties, by using any of TypeConverter, ICustomTypeDescriptor or TypeDescriptionProvider to provide runtime pseudo-properties. Can you give an example of what your parameters look like? I should be able to provide an example...


here's a basic example (everything is string, etc) based on an earlier reply (related but different):

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
                }}
            });
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文