gpt4 book ai didi

c# - 如何在属性网格中显示动态对象?

转载 作者:太空狗 更新时间:2023-10-29 23:58:33 24 4
gpt4 key购买 nike

我有一个自定义对象类型,它必须在 PropertyGrid 中可编辑:

public class CustomObjectType
{
public string Name { get; set; }
public List<CustomProperty> Properties {get; set;}
}

其中有一个自定义属性列表:

public class CustomProperty
{
public string Name { get; set; }
public string Desc { get; set; }
public Object DefaultValue { get; set; }
Type type;

public Type Type
{
get
{
return type;
}
set
{
type = value;
DefaultValue = Activator.CreateInstance(value);
}
}
}

这里的主要问题是 PropertyGrid 控件不允许编辑,也不允许对属性 DefaultValue 使用适当的编辑工具,该属性预先通过设置 的值实例化code>CustomProperty 的字段 Type

DefaultValue 的类型仅在运行时已知。

此外,我需要为 CustomProperty 的属性 Type 提供自定义 TypeConverter 以显示支持类型的下拉列表(对于例如,IntStringColorMyOwnClass)。

我该怎么做?

最佳答案

要走这条路,您需要为每个属性创建一个自定义 PropertyDescriptor。然后,您将通过自定义 TypeConverter 或(或者)ICustomTypeDescriptor/TypeDescriptionProvider 公开它。示例:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
[TypeConverter(typeof(CustomObjectType.CustomObjectConverter))]
public class CustomObjectType
{
[Category("Standard")]
public string Name { get; set; }
private readonly List<CustomProperty> props = new List<CustomProperty>();
[Browsable(false)]
public List<CustomProperty> Properties { get { return props; } }

private Dictionary<string, object> values = new Dictionary<string, object>();

public object this[string name]
{
get { object val; values.TryGetValue(name, out val); return val; }
set { values.Remove(name); }
}

private class CustomObjectConverter : ExpandableObjectConverter
{
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
var stdProps = base.GetProperties(context, value, attributes);
CustomObjectType obj = value as CustomObjectType;
List<CustomProperty> customProps = obj == null ? null : obj.Properties;
PropertyDescriptor[] props = new PropertyDescriptor[stdProps.Count + (customProps == null ? 0 : customProps.Count)];
stdProps.CopyTo(props, 0);
if (customProps != null)
{
int index = stdProps.Count;
foreach (CustomProperty prop in customProps)
{
props[index++] = new CustomPropertyDescriptor(prop);
}
}
return new PropertyDescriptorCollection(props);
}
}
private class CustomPropertyDescriptor : PropertyDescriptor
{
private readonly CustomProperty prop;
public CustomPropertyDescriptor(CustomProperty prop) : base(prop.Name, null)
{
this.prop = prop;
}
public override string Category { get { return "Dynamic"; } }
public override string Description { get { return prop.Desc; } }
public override string Name { get { return prop.Name; } }
public override bool ShouldSerializeValue(object component) { return ((CustomObjectType)component)[prop.Name] != null; }
public override void ResetValue(object component) { ((CustomObjectType)component)[prop.Name] = null; }
public override bool IsReadOnly { get { return false; } }
public override Type PropertyType { get { return prop.Type; } }
public override bool CanResetValue(object component) { return true; }
public override Type ComponentType { get { return typeof(CustomObjectType); } }
public override void SetValue(object component, object value) { ((CustomObjectType)component)[prop.Name] = value; }
public override object GetValue(object component) { return ((CustomObjectType)component)[prop.Name] ?? prop.DefaultValue; }
}
}


public class CustomProperty
{
public string Name { get; set; }
public string Desc { get; set; }
public object DefaultValue { get; set; }
Type type;

public Type Type
{
get
{
return type;
}
set
{
type = value;
DefaultValue = Activator.CreateInstance(value);
}
}
}

static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
var obj = new CustomObjectType
{
Name = "Foo",
Properties =
{
new CustomProperty { Name = "Bar", Type = typeof(int), Desc = "I'm a bar"},
new CustomProperty { Name = "When", Type = typeof(DateTime), Desc = "When it happened"},
}
};
Application.Run(new Form { Controls = { new PropertyGrid { SelectedObject = obj, Dock = DockStyle.Fill } } });
}
}

关于c# - 如何在属性网格中显示动态对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3491556/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com