据我了解,属性网格被赋予一个对象,它可以通过使用反射提取其属性来操作该对象。
我的问题是我有一组在运行时确定的参数,因此我无法静态地组成一个具有属性的类来表示这组参数。
我有两个想法来解决这个问题,但这两个想法都很复杂,并且可能会消耗大量时间,事实上,我会说它们在我的时间限制下不切实际。一种是使用 Reflection Emit 动态定义类,另一种是动态构建 C# 源文件,然后使用 CodeDom 编译它。
属性网格可以以不同的方式表现(除了使用反射提取对象的属性之外)来满足我的问题吗?
如果没有,您知道还有其他控件可以帮我完成这项工作吗?
我想说,我从一开始就使用属性网格的原因是它能够为常见类型提供非常好的数据检索 UI。对于颜色,您会自动获得调色板,对于数据时间,您会自动拥有一个不错的日历。如果可能的话,我想自动获取这些东西。
Yes, PropertyGrid
可以展示东西other不仅仅是编译时属性,通过使用任何TypeConverter
, ICustomTypeDescriptor
or TypeDescriptionProvider
提供运行时伪属性。你能举例说明你的参数是什么样的吗?我应该能够提供一个例子......
这是一个基本示例(一切都是string
等)基于较早回复 https://stackoverflow.com/questions/882214/data-binding-dynamic-data/882246#882246(相关但不同):
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
}}
});
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)