在运行时更改Browsable属性(C#)

8

我正在尝试在运行时更改一个类中变量的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仍然没有显示为属性,因此我的方法存在问题,但我不知道是什么。

你不能使用声明性属性,它们是固定的。你可以在这里检查我的答案,获取完整的动态属性描述符:https://dev59.com/oHfZa4cB1Zd3GeqPNRdd - Simon Mourier
3个回答

3

RefreshPropertiesAttribute 类 指示当关联属性值更改时,属性网格应刷新。

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

1

除非您具有其TypeDescriptor显式声明,否则无法获取一个确切属性的Browsable属性。 在您的情况下,GetField(“browsable”)将返回所有属性的FieldInfo并将它们切换为可见true。 如果您有一些属性并将一个browsable设置为false,则会隐藏所有属性。

为所需属性提供自定义TypeDescriptor或使用一些解决方案,例如https://www.codeproject.com/articles/7852/propertygrid-utilities


1

我知道这个问题是一段时间之前的,但是今天我通过在更改Browsable属性后调用propertiesGrid.Refresh()来解决了相同的问题。也许将来会有人受益。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接