2014-09-26 89 views
0

我想使用屬性網格來顯示對象之間的差異。一切都很好,但我怎樣才能突出(改變回或前顏色)的屬性有差異? 這可能嗎?Winforms PropertyGrid風格

也許有人建議這種控制的替代品有良好的對象差異的可視化?

回答

0

期間在不同的文章中,我喜歡的是它明確的方式是不可能的,爲什麼通過@Hans帕桑特指出 尼斯解釋搜索 Can we change the text/background color of an individual property in PropertyGrid

而且它已經從VisualHint公司不錯,但不是免費的替代 Smart PropertyGrid.Net

但是我的情況可能會破解現有的功能,因爲我只需要一種顏色來顯示屬性的差異。我所做的只是使用屬性DisabledItemForeColor,它爲ReadOnly屬性定義顏色,並將ReadOnly屬性映射到自定義屬性HasDifference。

因此,這裏是我的示例代碼:

public Form1() 
    { 
     InitializeComponent(); 

     Application.EnableVisualStyles(); 
     var obj = new CustomObjectType 
     { 
      ObjectName = "CompositeFirst", 
      Properties = 
      { 
       new CustomProperty { Name = "Property1", Type = typeof(int), Desc = "Property1 desc", DefaultValue = 1, HasDifference = true}, 
       new CustomProperty { Name = "Property2", Type = typeof(DateTime), Desc = "Property2 desc"}, 
       new CustomProperty { Name = "Property1", Type = typeof(CustomObjectType), HasDifference = true}, 
      } 
     }; 

     var customObjectType = obj.Properties[2].DefaultValue as CustomObjectType; 
     if (customObjectType != null) 
      customObjectType.ObjectName = "CompositSecond"; 
      customObjectType.Properties = new List<CustomProperty> 
      { 
       new CustomProperty { Name = "Property4", Type = typeof(int), DefaultValue = 5, HasDifference = true}, 
       new CustomProperty { Name = "Property5", Type = typeof(DateTime), Desc = "Property2 desc", DefaultValue = DateTime.Now}, 
      }; 

     propertyGrid1.SelectedObject = obj;  
     propertyGrid1.DisabledItemForeColor = Color.Red; 
    } 


    [TypeConverter(typeof(CustomObjectConverter))] 
    public class CustomObjectType : TypeConverter 
    { 
     private List<CustomProperty> _props = new List<CustomProperty>(); 

     [Browsable(false)] 
     public string ObjectName 
     { 
      get; 
      set; 
     } 

     [Browsable(false)] 
     public List<CustomProperty> Properties 
     { 
      get { return _props; } 
      set { _props = value; } 
     } 

     private readonly Dictionary<string, object> values = new Dictionary<string, object>(); 

     public object this[string name] 
     { 
      get { object val; values.TryGetValue(name, out val); return val; } 
      set { values.Remove(name); } 
     } 

     private class CustomObjectConverter : ExpandableObjectConverter 
     { 
      public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 
      { 
       var stdProps = base.GetProperties(context, value, attributes); 
       var obj = value as CustomObjectType; 
       var customProps = obj == null ? null : obj.Properties; 
       var props = new PropertyDescriptor[stdProps.Count + (customProps == null ? 0 : customProps.Count)]; 
       stdProps.CopyTo(props, 0); 
       if (customProps != null) 
       { 
        int index = stdProps.Count; 
        foreach (CustomProperty prop in customProps) 
        { 
         props[index++] = new CustomPropertyDescriptor(prop); 
        } 
       } 
       return new PropertyDescriptorCollection(props); 
      } 

      public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
      { 
       if (value is CustomObjectType) 
       { 
        return (value as CustomObjectType).ObjectName;  
       } 
       return base.ConvertTo(context, culture, value, destinationType); 
      } 
     } 

     private class CustomPropertyDescriptor : PropertyDescriptor 
     { 
      private readonly CustomProperty _prop; 
      public CustomPropertyDescriptor(CustomProperty prop) 
       : base(prop.Name, null) 
      { 
       _prop = prop; 
      }     

      public override bool IsReadOnly { get { return _prop.HasDifference; } } 
      public override string Category { get { return "Main Category"; } } 
      public override string Description { get { return _prop.Desc; } } 
      public override string Name { get { return _prop.Name; } } 
      public override bool ShouldSerializeValue(object component) { return ((CustomObjectType)component)[_prop.Name] != null; } 
      public override void ResetValue(object component) { ((CustomObjectType)component)[_prop.Name] = null; }     
      public override Type PropertyType { get { return _prop.Type; } } 
      public override bool CanResetValue(object component) { return true; } 
      public override Type ComponentType { get { return typeof(CustomObjectType); } } 
      public override void SetValue(object component, object value) { ((CustomObjectType)component)[_prop.Name] = value; } 
      public override object GetValue(object component) { return ((CustomObjectType)component)[_prop.Name] ?? _prop.DefaultValue; } 
     } 
    } 

    public class CustomProperty 
    { 
     public string Name { get; set; } 
     public string Desc { get; set; } 
     public object DefaultValue { get; set; } 
     public bool HasDifference { get; set; } 

     Type _type; 

     public Type Type 
     { 
      get 
      { 
       return _type; 
      } 
      set 
      { 
       _type = value; 
       DefaultValue = Activator.CreateInstance(value); 
      } 
     } 
    } 
} 

它看起來是這樣的:

Highlighting property

希望這將有助於給別人。

+1

嗨,也許愚蠢的問題,但只有你現在只讀的紅色屬性嗎?我需要做同樣的事情。 – toddmo 2015-02-20 20:44:48