C# 对象级别上的PropertyGrid只读属性

C# 对象级别上的PropertyGrid只读属性,c#,.net,propertygrid,propertydescriptor,readonly-attribute,C#,.net,Propertygrid,Propertydescriptor,Readonly Attribute,我想在我的PropertyGrid中显示一个类的多个实例。该类如下所示: public class Parameter { [Description("the name")] public string Name { get; set; } [Description("the value"), ReadOnly(true)] public string Value { get; set; } [Description("the description"

我想在我的
PropertyGrid
中显示一个类的多个实例。该类如下所示:

public class Parameter
{
    [Description("the name")]
    public string Name { get; set; }

    [Description("the value"), ReadOnly(true)]
    public string Value { get; set; }

    [Description("the description")]
    public string Description { get; set; }
}
我在
树视图中有许多该类的实例。当我在我的
TreeView
中选择其中一个属性时,属性将按预期显示在
PropertyGrid
中。到目前为止还不错,但我想通过以下方式定制此行为:

对于每个实例,我希望能够阻止用户修改特定属性。通过在我的类中设置
ReadOnly(true)
(如上面的示例所示),将在类级别禁用所有
Value
属性

经过一些研究,我发现了以下解决方案,它使我有机会在运行时启用/禁用特定属性:

PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this)["Value"];

ReadOnlyAttribute attr = 
        (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];

FieldInfo isReadOnly = attr.GetType().GetField(
        "isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);

isReadOnly.SetValue(attr, false);
这种方法工作得很好,但不幸的是,它也只在类级别上工作。这意味着如果我将
isReadOnly
设置为
false
,则我的
参数
-对象的
属性都是可写的。但我只想在一个特定的对象上使用它(因此是对象级别)。我真的不想为读/写和只读属性创建单独的类

由于我的想法越来越少,非常感谢您的帮助:)

提前谢谢


编辑:我需要将只读属性灰显,以便用户可以看到不允许或不可能编辑它们。

您可以使用自定义类型描述符包装对象,但我认为这太过分了,因为您必须创建一个新的typedescriptor派生类

因此,一个最简单的解决方案是设置一个标志,类似于:

public class Parameter 
{ 
    private string thevalue;

    [Browsable(false)]
    public bool CanEditValue { get; set; }

    [Description("the name")] 
    public string Name { get; set; } 

    [Description("the description")] 
    public string Description { get; set; }

    [Description("the value"), ReadOnly(true)] 
    public string Value { 
        get { return this.thevalue; }
        set { if (this.CanEditValue) this.thevalue = value; } 
    }
}

编辑:链接文章已被删除(我希望只是暂时的)。你可以在答案中找到一个可行的替代方案。基本上,您必须(在运行时)通过
TypeDescriptor
为该属性添加
ReadOnlyAttribute


看看这个古老而漂亮的工具,它包含了许多用于
PropertyGrid
的有用工具


基本上,您提供了一个类或委托,用于获取属性的属性。因为它将通过要获取属性的对象的实例被调用,所以您可以返回(或不返回)每个对象的
ReadOnlyAttribute
。简而言之:对您的属性应用
PropertyAttributesProviderAttribute
,编写您自己的提供程序,并基于对象本身(而不是类)替换
PropertyAttributes
集合中的属性。

您好,Jaime,您的建议可以接受,因为它非常简单。我尝试了这一点,不幸的是,在setter中进行检查并没有禁用属性编辑,比如ReadOnly(true)…所以它没有变灰。用户会认为它是可更改的,但他们的输入将被丢弃。还有其他不那么复杂的想法吗?:)恐怕您唯一的选择是派生属性描述符并实现条件IsReadOnly属性getter。我已经阅读了整个文档,但仍然不理解您的想法。你能给我一个小的代码示例让它更清楚一点吗?感谢您的时间:)请参阅文章中的动态用法一段。简而言之:将PropertyAttributesProviderAttribute应用于您的属性,编写您自己的提供程序并基于对象本身(而不是类)替换PropertyAttributes集合中的属性。正如我在源代码中看到的,这需要使用作者自定义PropertyGrid实现才能使其正常工作?在我的例子中,我必须使用DLL中现有的PropertyGrid(我无法修改)。@Inferno否,所有操作都是通过自定义属性和类型描述符完成的。最终解决了这个问题。我忘了把TypeConverterAttribute放在班上的第一名。仍然有很多代码可以解决这样一个小问题……但最重要的是它现在正在工作。谢谢