在运行时更改可浏览属性(C#)

时间:2015-07-09 15:16:27

标签: c# attributes treeview propertygrid

我试图在运行时在我的一个类中更改变量的Browsable属性。包含该属性的类如下所示:

public class DisplayWallType : WallType
    {
        [TypeConverter(typeof(SheathingOptionsConverter))]
        [Browsable(false)]
        public override Sheathing SheathingType { get; set; }

        public DisplayWallType(string passedName, string passedType, bool passedMirrorable, Distance passedHeight, string passedStudPattern, Distance passedStudSpacing, VaporBarrier passedBarrier)
            : base(passedName, passedType, passedMirrorable, passedHeight, passedStudPattern, passedStudSpacing, passedBarrier)
        {

        }

        /// <summary>
        /// Empty constructor for XML serialization
        /// </summary>
        public DisplayWallType()
        {

        }
    }

我最初为SheathingType设置为false,因为我不希望该属性以我的应用程序的第一种形式显示。但是,我确实希望它在我的第二种形式中可见,所以我有这种方法来改变它

private void _makeSheathingVisible(DisplayWallType wallTypeToMakeSheathingVisible)
        {
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(wallTypeToMakeSheathingVisible.GetType())["SheathingType"];
            BrowsableAttribute attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
            FieldInfo isBrow = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
            isBrow.SetValue(attrib, true);
        }

上面的方法采用DisplayWallType对象并确保将Browsable设置为true。我的第二种形式是树形视图和属性网格。树视图使用DisplayWallType实例填充,当选择一个时,将其传递给该方法,以便SheathingType在PropertiesGrid中显示父类的其余属性。

enter image description here

但是,SheathingType仍然没有显示为属性,所以我的方法有问题,但我不知道是什么

3 个答案:

答案 0 :(得分:1)

除了Browsable明确声明之外,您无法获得一个确切属性的TypeDescriptor属性。在您的情况下,GetField("browsable")将为所有属性返回FieldInfo,并将其切换为可见的true。如果你有一些属性并将一个可浏览设置为false,则会出现同样的事情 - 它将隐藏所有属性。

为所需属性提供自定义TypeDescriptor或使用https://www.codeproject.com/articles/7852/propertygrid-utilities之类的解决方案。

答案 1 :(得分:1)

RefreshPropertiesAttribute Class表示当关联的属性值更改时,属性网格应刷新。

    [TypeConverter(typeof(SheathingOptionsConverter))]
    [Browsable(false)] // changes at runtime
    public override Sheathing SheathingType { get; set; }

    private bool updateWhenChanged;

    [RefreshProperties(RefreshProperties.All)]
    public bool UpdateWhenChanged 
    {
        get => updateWhenChanged;
        set
        {
            if (updateWhenChanged != value)
            {
                SetBrowsableAttributeValue(nameof(SheathingType), value);

                updateWhenChanged = value;
            }
        }
    }

    private void SetBrowsableAttributeValue(string attribute, object value)
    {
        var descriptor = TypeDescriptor.GetProperties(GetType())[attribute];
        var attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
        var isBrow = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
        isBrow.SetValue(attrib, value);
    }

答案 2 :(得分:0)

我知道这个问题是从前一段时间开始的,但是今天我通过更改Browsable属性后调用propertiesGrid.Refresh()来解决了同一问题。也许将来对某人有帮助。