8

我想在我的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。当我在其中选择其中一个时TreeView,属性会PropertyGrid按预期显示。到目前为止一切顺利,但我想通过以下方式自定义此行为:

对于每个单独的实例,我希望能够防止用户修改特定属性。通过ReadOnly(true)在我的班级中设置(如您在上面的示例中所见),所有Value属性都将在class-level上禁用。

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

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

这种方法工作得很好,但不幸的是也仅限于类级别。这意味着如果我将Value's设置isReadOnlyfalse,我的所有Parameter-objects 都具有Value可写属性。但我只希望在那个特定的对象上(因此是object-level)。我真的不想为读/写和只读属性创建单独的类。

由于我的想法不多了,非常感谢您的帮助:)

提前致谢!

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

4

2 回答 2

5

编辑:链接的文章已被删除(我希望只是暂时的)。您可以在How to add property-level Attribute to the TypeDescriptor at runtime?的答案中找到一个可行的替代方案?. 基本上,您必须ReadOnlyAttribute通过 aTypeDescriptor为该属性添加(在运行时)。


看看这篇关于 CodeProject 的旧但不错的文章,它包含很多有用的工具PropertyGrid

基本上,您提供一个类或一个委托,用于获取您的属性的属性。因为它将被调用传递您想要获取属性的对象的实例,所以您将能够返回(或不返回)ReadOnlyAttribute每个对象的基础。很快:将 aPropertyAttributesProviderAttribute应用于您的属性,编写您自己的提供程序并PropertyAttributes根据对象本身(而不是类)替换集合中的属性

于 2012-05-07T12:49:15.880 回答
1

您可以使用自定义类型描述符包装对象,但我认为这将是矫枉过正,因为您必须创建一个新的类型描述符派生类。

因此,最简单的解决方案是设置一个标志,例如:

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; } 
    }
}
于 2012-05-07T12:47:22.177 回答