【问题标题】:C# .Net 4.5 PropertyGrid: how to hide PropertiesC# .Net 4.5 PropertyGrid:如何隐藏属性
【发布时间】:2013-09-26 09:26:04
【问题描述】:

问题很简单(我希望这有一个简单的解决方案!):我想在它为零时隐藏( Browsable(false) )属性“Element”(在我的 PropertyGrid 对象中)。

    public class Question
    {
       ...

      public int Element
      {
        get; set;
      }
    }

【问题讨论】:

  • 不简单,属性没有条件。您已经到了 PropertyGrid 不再有用的地步。然后,您切换到每个属性都有控件的表单。现在又简单了。

标签: c# .net properties propertygrid


【解决方案1】:

当我多年前想解决这个问题时,我记得,属性 [Browsable] 不起作用。我发现它现在很好用,但我也通过创建代理对象的方式解决了问题。

有代码: https://github.com/NightmareZ/PropertyProxy

您可以使用属性突出显示所需的属性,然后创建代理对象,该对象仅将突出显示的属性转发到 PropertyGrid 控件。

public class Question
{
   ...
  
  [PropertyProxy]
  public int Element
  {
    get; set;
  }
}

...

var factory = new PropertyProxyFactory();
var question = new Question();
var proxy = factory.CreateProxy(question);
propertyGrid.SelectedObject = proxy;

【讨论】:

    【解决方案2】:

    对我来说,在 PropertGrid 和自定义控件中隐藏属性的最简单方法是:

    public class Question
    {
       ...
      
      [Browsable(false)]
      public int Element
      {
        get; set;
      }
    }
    

    要动态执行此操作,您可以使用 code,其中 Question 是您的类,您的属性是 Element,因此您可以在不从集合中删除元素的情况下显示或隐藏它:

    PropertyDescriptorCollection propCollection = TypeDescriptor.GetProperties(Question.GetType());
    PropertyDescriptor descriptor = propCollection["Element"];
    
    BrowsableAttribute attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
    FieldInfo isBrow = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
    //Condition to Show or Hide set here:
    isBrow.SetValue(attrib, true);
    propertyGrid1.Refresh(); //Remember to refresh PropertyGrid to reflect your changes
    

    所以要完善答案:

    public class Question
    {
       ...
       private int element;
       [Browsable(false)]
       public int Element
       {
          get { return element; }
          set { 
                element = value; 
                PropertyDescriptorCollection propCollection = TypeDescriptor.GetProperties(Question.GetType());
                PropertyDescriptor descriptor = propCollection["Element"];
        
                BrowsableAttribute attrib = (BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
                FieldInfo isBrow = attrib.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
                if(element==0)
                {
                  isBrow.SetValue(attrib, false);
                }
                else
                {
                  isBrow.SetValue(attrib, true);
                }
              }
       }
    }
    

    【讨论】:

    • 这不是动态的,在运行时不起作用,所以它不能回答问题。
    • 可以在运行时设置Browsable属性,见stackoverflow.com/a/47836429/1518546
    • 如何动态地做到这一点?
    【解决方案3】:

    您可以做的是重用我在此问题的答案中描述的DynamicTypeDescriptor 类:PropertyGrid Browsable not found for entity framework created property, how to find it?

    例如这样:

    public Form1()
    {
        InitializeComponent();
    
        DynamicTypeDescriptor dt = new DynamicTypeDescriptor(typeof(Question));
    
        Question q = new Question(); // initialize question the way you want    
        if (q.Element == 0)
        {
            dt.RemoveProperty("Element");
        }
        propertyGrid1.SelectedObject = dt.FromComponent(q);
    }
    

    【讨论】:

      【解决方案4】:

      试试 BrowsableAttributes/BrowsableProperties 和 HiddenAttributes/HiddenProperties:

      More info here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-07
        • 2020-01-29
        • 2019-11-04
        相关资源
        最近更新 更多