C#中的PropertyGrid綁定對象,通過改變某一值而動態設置部分屬性的特性


問題:如下,我定義了一個對象,默認設置屬性WindowSize ,WindowSize 為不可見,通過改變SaveOnClose的值,動態的改變不可見的屬性的顯示和隱藏。

 [DefaultPropertyAttribute("SaveOnClose")]  
     public class AppSettings{  
          private bool saveOnClose = false;  
          private Size windowSize = new Size(100,100);  
          private Font windowFont = new Font("宋體", 9, FontStyle.Regular);  
          [CategoryAttribute("文檔設置"),  
          DefaultValueAttribute(true)]  
          public bool SaveOnClose  
          {  
              get { return saveOnClose; }  
              set { saveOnClose = value;}  
          }  
          [CategoryAttribute("文檔設置"),
           Browsable(false)]  
          public Size WindowSize   
          {  
              get { return windowSize; }  
              set { windowSize = value;}  
          }  
          [CategoryAttribute("文檔設置"),
           Browsable(false),]  
          public Font WindowFont   
          {  
              get {return windowFont; }  
              set { windowFont = value;}  
          }  
}

那么,現在,既然有屬性的特性Browsable,可以設置屬性的顯示和隱藏,我們就可以通過改變這個參數的值,從而達到我們想要的效果。如下:

       void SetPropertyVisibility(object obj, string propertyName, bool visible)
        {
            Type type = typeof(BrowsableAttribute);
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
            AttributeCollection attrs = props[propertyName].Attributes;
            FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic);
            fld.SetValue(attrs[type], visible);
        }
        void SetPropertyReadOnly(object obj, string propertyName, bool readOnly)
        {
            Type type = typeof(System.ComponentModel.ReadOnlyAttribute);
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
            AttributeCollection attrs = props[propertyName].Attributes;
            FieldInfo fld = type.GetField("isReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance);
            fld.SetValue(attrs[type], readOnly);
        }

以上方法,不用我說。一看就知道用途了吧,通過如下方法去調用:

private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            var item = propertyGrid1.SelectedObject;
            bool b = (bool)e.ChangedItem.Value;
            if (b)
            {
                SetPropertyVisibility(item, "WindowSize", b);//WindowSize必須是自定義屬性中的屬性名,如下也是
                SetPropertyVisibility(item, "WindowFont", b);
                //SetPropertyReadOnly(item, "WindowFont", b);
            }
            else
            {
                SetPropertyVisibility(item, "WindowSize", b);
                SetPropertyVisibility(item, "WindowFont", b);
                //SetPropertyReadOnly(item, "WindowFont", b);
            }
            propertyGrid1.SelectedObject = item;  
        }

通過以上方法就可以達到效果了。 需要注意幾點:

  1.SetPropertyVisibility方法,SetPropertyReadOnly方法中的參數分別指:(item,’自定義屬性對象中的某個屬性名‘,值)

   2.上述方法調用完后,記得需要再次 propertyGrid1.SelectedObject = item; 否則,是沒有效果的

參考文獻:http://bbs.csdn.net/topics/350150747


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM