定义自定义属性 class 使 属性 在某些情况下可浏览

Define a custom Attribute class to make a property Browsable in some conditions

我的项目中有一些 类,一些属性是 Browsable(false) 所以用户看不到它们:

public class OrderEntity{
    public int Id { get; set;}   
    [Browsable(false)]
    public int ProductId { get; set;}   
    ....
}

我想,如果最终用户是管理员,他可以看到ProductId,但另一个用户看不到它。

所以我需要这样的东西:

public class OrderEntity{
    public int Id { get; set;}   
    [CustomizedBrowsable(false)]
    public int ProductId { get; set;}   
    ....
}


public class CustomizedBrowsable: Attribute
{
  if(AppContext.UserCode == "Admin") // The current user code saved in a static variable AppContext.UserCode.
    //do somethings   
  else
    //do somethings else 
}

这不是您可以通过属性执行的操作,因为 BrowsableAttributesealed。要通过绑定 做到这一点 ,您需要一个自定义类型描述符 - 因此您需要在您的类型上实现 ICustomTypeDescriptor(直接或通过 TypeDescriptionProvider) ,提供自定义 PropertyDescriptor,并更改可浏览性的定义方式 IsBrowsable,IIRC)。

这是的工作量。

坦率地说,在几乎所有情况下,最好只手动控制绑定,并且只在检查安全级别后添加列/输入/其他内容。

我使用 Browsable class 代码定义了自己的 AdminBrowsable class:

[AttributeUsage(AttributeTargets.All)]
public sealed class AdminBrowsableAttribute : Attribute
{
    /// <summary>
    /// Specifies that a property or event can be modified at design time. This static field is read-only.
    /// </summary>
    public static readonly AdminBrowsableAttribute Yes = new AdminBrowsableAttribute(true);
    /// <summary>
    /// Specifies that a property or event cannot be modified at design time. This static field is read-only.
    /// </summary>
    public static readonly AdminBrowsableAttribute No = new AdminBrowsableAttribute(false);
    /// <summary>
    /// Specifies the default value for the <see cref="T:System.ComponentModel.BrowsableAttribute"/>, which is <see cref="F:System.ComponentModel.BrowsableAttribute.Yes"/>. This static field is read-only.
    /// </summary>
    public static readonly AdminBrowsableAttribute Default = AdminBrowsableAttribute.Yes;
    private bool browsable = true;

    /// <summary>
    /// Gets a value indicating whether an object is browsable.
    /// </summary>
    /// 
    /// <returns>
    /// true if the object is browsable; otherwise, false.
    /// </returns>
    public bool Browsable
    {
        get
        {
            return this.browsable;
        }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.ComponentModel.BrowsableAttribute"/> class.
    /// </summary>
    /// <param name="browsable">true if a property or event can be modified at design time; otherwise, false. The default is true. </param>
    public AdminBrowsableAttribute(bool browsable)
    {
        if (!AppContext.IsAdmin)
        {
            this.browsable = browsable;
        }
    }

    /// <summary>
    /// Indicates whether this instance and a specified object are equal.
    /// </summary>
    /// 
    /// <returns>
    /// true if <paramref name="obj"/> is equal to this instance; otherwise, false.
    /// </returns>
    /// <param name="obj">Another object to compare to. </param>
    public override bool Equals(object obj)
    {
        if (obj == this)
            return true;
        AdminBrowsableAttribute browsableAttribute = obj as AdminBrowsableAttribute;
        if (browsableAttribute != null)
            return browsableAttribute.Browsable == this.browsable;
        return false;
    }

    /// <summary>
    /// Returns the hash code for this instance.
    /// </summary>
    /// 
    /// <returns>
    /// A 32-bit signed integer hash code.
    /// </returns>
    public override int GetHashCode()
    {
        return this.browsable.GetHashCode();
    }

    /// <summary>
    /// Determines if this attribute is the default.
    /// </summary>
    /// 
    /// <returns>
    /// true if the attribute is the default value for this attribute class; otherwise, false.
    /// </returns>
    public override bool IsDefaultAttribute()
    {
        return this.Equals((object)AdminBrowsableAttribute.Default);
    }
}

我只更改了 Constructor:

public AdminBrowsableAttribute(bool browsable)
{
    if (AppContext.UserCode != "Admin")
    {
        this.browsable = browsable;
    }
}