.Net如何为用户控件的属性设置IsReadOnly [英] .Net how to set IsReadOnly for a property for a usercontrol

查看:60
本文介绍了.Net如何为用户控件的属性设置IsReadOnly的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.NET中有一个具有2个新属性的用户控件

  Prop1:布尔值Prop2:字符串 

当用户将 Prop1 设置为 false 时,我想在属性网格中创建 Prop2 READONLY .

解决方案

如果要基于某些条件在运行时将属性外观设置为只读(灰色),则需要分配

进一步阅读

您可以在以下文章中了解其他一些解决方案:

I have a user control in .NET with 2 new property

Prop1: Boolean
Prop2: String

I want to make Prop2 READONLY in the property grid when the user set Prop1 to false.

解决方案

If you want to make the property appearance read-only (gray) at run-time based on some criteria, you need to assign a CustomTypeDescriptor to your class which provides metadata about your class for property grid.

PropertyGrid control uses the type descriptor of the object to extract information about its properties to show. The type descriptor, returns a list of PropertyDescriptor objects as list of properties. Each PropertyDescriptor contains some methods and properties to return display name, description, and other information about the property. IsReadOnly property of the PropertyDescriptor is responsible to inform the PropertyGrid if the property should be read only.

Example

In the following example, I created a class containing two properties. Editable and StringProperty. If the Editable is true then StringProperty is editable, otherwise it would be read-only and will be shown as gray in PropertyGrid.

MyPropertyDescriptor

It's responsible to provide metadata for property. When implementing this class, for most properties, we will use the trivial implementation which uses original property's implementations, but for IsReadOnly we will decide based on the value of Editable property of the owner object:

using System;
using System.ComponentModel;
using System.Linq;
public class MyPropertyDescriptor : PropertyDescriptor
{
    PropertyDescriptor p;
    SampleClass o;
    public MyPropertyDescriptor(PropertyDescriptor originalProperty, SampleClass owenr)
        : base(originalProperty) { p = originalProperty; o = owenr; }
    public override bool CanResetValue(object component)
    { return p.CanResetValue(component); }
    public override object GetValue(object component) { return p.GetValue(component); }
    public override void ResetValue(object component) { p.ResetValue(component); }
    public override void SetValue(object component, object value)
    { p.SetValue(component, value); }
    public override bool ShouldSerializeValue(object component)
    { return p.ShouldSerializeValue(component); }
    public override AttributeCollection Attributes { get { return p.Attributes; } }
    public override Type ComponentType { get { return p.ComponentType; } }
    public override bool IsReadOnly { get { return !o.Editable; } }
    public override Type PropertyType { get { return p.PropertyType; } }
}

MyTypeDescriptor

It's responsible to provide a list of properties for the object. For StringProperty which we are going to change its behavior at run-time, we will return a MyPropertyDescriptor:

using System;
using System.ComponentModel;
using System.Linq;
public class MyTypeDescriptor : CustomTypeDescriptor
{
    ICustomTypeDescriptor d;
    SampleClass o;
    public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor, SampleClass owner)
        : base(originalDescriptor) { d = originalDescriptor; o = owner; }
    public override PropertyDescriptorCollection GetProperties()
    { return this.GetProperties(new Attribute[] { }); }
    public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>()
            .Select(p => p.Name == "StringProperty" ? new MyPropertyDescriptor(p, o) : p)
            .ToArray();
        return new PropertyDescriptorCollection(properties);
    }
}

MyTypeDescriptionProvider

It's responsible to return a type descriptor for your object, when someone (like property grid) request type description:

using System;
using System.ComponentModel;
public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
    public MyTypeDescriptionProvider()
        : base(TypeDescriptor.GetProvider(typeof(object))) { }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type type, object o)
    {
        ICustomTypeDescriptor baseDescriptor = base.GetTypeDescriptor(type, o);
        return new MyTypeDescriptor(baseDescriptor, (SampleClass)o);
    }
}

SampleClass

At last, the implementation of the class:

using System;
using System.ComponentModel;
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public class SampleClass
{
    [RefreshProperties(RefreshProperties.All)]
    public bool Editable { get; set; }
    string sp;
    public string StringProperty
    {
        get { return sp; }
        set
        {
            if (Editable)
                sp = value;
        }
    }
}

Result

Further reading

You can read about some other solutions in the following post:

这篇关于.Net如何为用户控件的属性设置IsReadOnly的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆