2017-06-01 161 views
0

我需要在運行時將自定義屬性添加到WPF Xceed屬性網格控件。我能找到的最好的解決辦法是在這裏提出的一個:自定義(動態)屬性 - WPF Xceed屬性網格

How to modify PropertyGrid at runtime (add/remove property and dynamic types/enums)

但是它僅適用於該財產的WinForms Grid控件。請參閱下面的代碼,以及我得到的結果。

我不是這方面的專家。是否有可能使代碼與Xceed Property Grid控件兼容?

enter image description here

 CustomClass myProperties = new CustomClass(); 

     propertyGrid.SelectedObject = myProperties; 

     myProperties.Add(new CustomProperty("Name", "Sven", typeof(string), false, true,"Cat1")); 
     myProperties.Add(new CustomProperty("Surname", "Bendo", typeof(string), false, true, "Cat1")); 
     myProperties.Add(new CustomProperty("Card", "Visa", typeof(string), false, true, "Cat2")); 
     myProperties.Add(new CustomProperty("Bank", "SB", typeof(string), false, true, "Cat2")); 

     propertyGrid.Update(); 

自定義類:

/// <summary> 
    /// CustomClass (Which is binding to property grid) 
    /// </summary> 
    public class CustomClass : CollectionBase, ICustomTypeDescriptor 
    { 
     /// <summary> 
     /// Add CustomProperty to Collectionbase List 
     /// </summary> 
     /// <param name="Value"></param> 
     public void Add(CustomProperty Value) 
     { 
      base.List.Add(Value); 
     } 

     /// <summary> 
     /// Remove item from List 
     /// </summary> 
     /// <param name="Name"></param> 
     public void Remove(string Name) 
     { 
      foreach (CustomProperty prop in base.List) 
      { 
       if (prop.Name == Name) 
       { 
        base.List.Remove(prop); 
        return; 
       } 
      } 
     } 

     /// <summary> 
     /// Indexer 
     /// </summary> 
     public CustomProperty this[int index] 
     { 
      get 
      { 
       return (CustomProperty)base.List[index]; 
      } 
      set 
      { 
       base.List[index] = (CustomProperty)value; 
      } 
     } 


     #region "TypeDescriptor Implementation" 
     /// <summary> 
     /// Get Class Name 
     /// </summary> 
     /// <returns>String</returns> 
     public String GetClassName() 
     { 
      return TypeDescriptor.GetClassName(this, true); 
     } 

     /// <summary> 
     /// GetAttributes 
     /// </summary> 
     /// <returns>AttributeCollection</returns> 
     public AttributeCollection GetAttributes() 
     { 
      return TypeDescriptor.GetAttributes(this, true); 
     } 

     /// <summary> 
     /// GetComponentName 
     /// </summary> 
     /// <returns>String</returns> 
     public String GetComponentName() 
     { 
      return TypeDescriptor.GetComponentName(this, true); 
     } 

     /// <summary> 
     /// GetConverter 
     /// </summary> 
     /// <returns>TypeConverter</returns> 
     public TypeConverter GetConverter() 
     { 
      return TypeDescriptor.GetConverter(this, true); 
     } 

     /// <summary> 
     /// GetDefaultEvent 
     /// </summary> 
     /// <returns>EventDescriptor</returns> 
     public EventDescriptor GetDefaultEvent() 
     { 
      return TypeDescriptor.GetDefaultEvent(this, true); 
     } 

     /// <summary> 
     /// GetDefaultProperty 
     /// </summary> 
     /// <returns>PropertyDescriptor</returns> 
     public PropertyDescriptor GetDefaultProperty() 
     { 
      return TypeDescriptor.GetDefaultProperty(this, true); 
     } 

     /// <summary> 
     /// GetEditor 
     /// </summary> 
     /// <param name="editorBaseType">editorBaseType</param> 
     /// <returns>object</returns> 
     public object GetEditor(Type editorBaseType) 
     { 
      return TypeDescriptor.GetEditor(this, editorBaseType, true); 
     } 

     public EventDescriptorCollection GetEvents(Attribute[] attributes) 
     { 
      return TypeDescriptor.GetEvents(this, attributes, true); 
     } 

     public EventDescriptorCollection GetEvents() 
     { 
      return TypeDescriptor.GetEvents(this, true); 
     } 

     public PropertyDescriptorCollection GetProperties(Attribute[] attributes) 
     { 
      PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count]; 
      for (int i = 0; i < this.Count; i++) 
      { 
       CustomProperty prop = (CustomProperty)this[i]; 
       newProps[i] = new CustomPropertyDescriptor(ref prop, attributes); 
      } 

      return new PropertyDescriptorCollection(newProps); 
     } 

     public PropertyDescriptorCollection GetProperties() 
     { 
      return TypeDescriptor.GetProperties(this, true); 
     } 

     public object GetPropertyOwner(PropertyDescriptor pd) 
     { 
      return this; 
     } 
     #endregion 

    } 

    /// <summary> 
    /// Custom property class 
    /// </summary> 
    public class CustomProperty 
    { 
     private string sName = string.Empty; 
     private string sCategory = ""; 
     private bool bReadOnly = false; 
     private bool bVisible = true; 
     private object objValue = null; 

     public CustomProperty(string sName, object value, Type type, bool bReadOnly, bool bVisible,string sCategory) 
     { 
      this.sName = sName; 
      this.objValue = value; 
      this.type = type; 
      this.bReadOnly = bReadOnly; 
      this.bVisible = bVisible; 
      this.sCategory = sCategory; 
     } 

     private Type type; 
     public Type Type 
     { 
      get { return type; } 
     } 

     public bool ReadOnly 
     { 
      get 
      { 
       return bReadOnly; 
      } 
     } 

     public string Name 
     { 
      get 
      { 
       return sName; 
      } 
     } 

     public string Category 
     { 
      get 
      { 
       return sCategory; 
      } 

     } 


     public bool Visible 
     { 
      get 
      { 
       return bVisible; 
      } 
     } 

     public object Value 
     { 
      get 
      { 
       return objValue; 
      } 
      set 
      { 
       objValue = value; 
      } 
     } 

    } 


    /// <summary> 
    /// Custom PropertyDescriptor 
    /// </summary> 
    public class CustomPropertyDescriptor : PropertyDescriptor 
    { 
     CustomProperty m_Property; 
     public CustomPropertyDescriptor(ref CustomProperty myProperty, Attribute[] attrs) : base(myProperty.Name, attrs) 
     { 
      m_Property = myProperty; 
     } 

     #region PropertyDescriptor specific 

     public override bool CanResetValue(object component) 
     { 
      return false; 
     } 

     public override Type ComponentType 
     { 
      get { return null; } 
     } 

     public override object GetValue(object component) 
     { 
      return m_Property.Value; 
     } 

     public override string Description 
     { 
      get { return m_Property.Name; } 
     } 

     public override string Category 
     { 
      get { return m_Property.Category; } 
     } 

     public override string DisplayName 
     { 
      get { return m_Property.Name; } 
     } 

     public override bool IsReadOnly 
     { 
      get { return m_Property.ReadOnly; } 
     } 

     public override void ResetValue(object component) 
     { 
      //Have to implement 
     } 

     public override bool ShouldSerializeValue(object component) 
     { 
      return false; 
     } 

     public override void SetValue(object component, object value) 
     { 
      m_Property.Value = value; 
     } 

     public override Type PropertyType 
     { 
      get { return m_Property.Type; } 
     } 

     #endregion 


    } 

回答

0

如果你想屬性添加到PropertyGrid ATT運行時,你應該AutoGenerateProperties屬性設置爲false,並添加PropertyDefinitions到控制本身,例如:

CustomClass myProperties = new CustomClass(); 
propertyGrid.AutoGenerateProperties = false; 
propertyGrid.SelectedObject = myProperties; 
propertyGrid.PropertyDefinitions.Add(new Xceed.Wpf.Toolkit.PropertyGrid.PropertyDefinition() { Category = "Cat1", DisplayName = "Name", TargetProperties = new string[] { "Name"} }); 
+0

我無法得到這個工作。一個空白的屬性網格是結果。你能否詳細說明你的答案? – user1035217