c# - 如何在 PropertyGrid 中显示对象的 "Value"属性

标签 c# winforms propertygrid

我正在尝试为一个具有事件系统的游戏制作一个编辑器,其中包含事件的基类,然后为每种类型创建一个实际上完成所有操作的另一个类。

因此,我有一个显示在 PropertyGrid 中的 BaseEvent 列表,并且集合编辑器作为列表打开。我准备了一个 TypeConverter,因此我有一个包含所有派生类的下拉列表,这些类显示在“Value”属性中。

一切正常,派生类的属性显示为“Value”的子级,但是一旦我想显示 BaseEvent 中的属性,“Value”属性就会消失,子级出现在根目录中,所以我无法更改事件的类型。

有没有办法让“Value”属性与 BaseEvent 属性同时出现?

//This allows to get a dropdown for the derived classes
public class EventTypeConverter : ExpandableObjectConverter
{
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(GetAvailableTypes());
    }

    /*
    ...
    */
}

[TypeConverter(typeof(EventTypeConverter))]
public abstract class BaseEvent
{
    public bool BaseProperty; //{ get; set; } If I set this as a property, "Value" disappears
}

public class SomeEvent : BaseEvent
{
    public bool SomeOtherProperty { get; set; }
}

//The object selected in the PropertyGrid is of this type
public class EventManager
{
    public List<BaseEvent> Events { get; set; } //The list that opens the collection editor
}

最佳答案

最后我找到了解决这个问题的方法:通过 GetProperties 方法和自定义 PropertyDescriptor:

public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
    //Get the base collection of properties
    PropertyDescriptorCollection basePdc = base.GetProperties(context, value, attributes);

    //Create a modifiable copy
    PropertyDescriptorCollection pdc = new PropertyDesctiptorCollection(null);
    foreach (PropertyDescriptor descriptor in basePdc)
        pdc.Add(descriptor);

    //Probably redundant check to see if the value is of a correct type
    if (value is BaseEvent)
        pdc.Add(new FieldDescriptor(typeof(BaseEvent), "BaseProperty"));
    return pdc;
}

public class FieldDescriptor : SimplePropertyDescriptor
{
    //Saves the information of the field we add
    FieldInfo field;

    public FieldDescriptor(Type componentType, string propertyName)
        : base(componentType, propertyName, componentType.GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic).FieldType)
    {
        field = componentType.GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic);
    }

    public override object GetValue(object component)
    {
        return field.GetValue(component);
    }

    public override void SetValue(object component, object value)
    {
        field.SetValue(component, value);
    }
}

关于c# - 如何在 PropertyGrid 中显示对象的 "Value"属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9655368/

相关文章:

c# - 在 PropertyGrid C# 中显示 DebuggerDisplay

visual-studio - 如何在 Visual Studio IDE 的“属性”窗口中更改字体大小

wpf - 在 WPF 中使用 .NET 2.0(Windows 窗体)控件的限制?

c# - 按钮 onClick 未绑定(bind)到 Activity 中的方法

c# - 如何启用 CORS 支持和 NTLM 身份验证

c# - 无法在全屏表单的底部或右侧绘制

c# - 未显示窗体时,窗体的保存位图/"screenshot"不起作用

c# - OptionalFieldAttribute 真的有效吗?

C#:如何正确处理 float

c# - 在不隐藏/阻塞任务栏的情况下最大化多屏环境中的窗口