c# - Winforms PropertyGrid 样式

标签 c# winforms propertygrid

我想使用属性网格来显示对象之间的差异。一切都很好,但是我如何突出显示(更改回或前景色)有差异的属性? 可能吗?

也许有人建议此控件的替代方案,以便更好地可视化对象差异?

最佳答案

在搜索不同的文章时,我发现这不可能以明确的方式进行 很好地解释了@Hans Passant 指出的原因 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

希望它能对某人有所帮助。

关于c# - Winforms PropertyGrid 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26055673/

相关文章:

c# - C# 中的逆变

C# - 列表框不显示项目

c# - 如何使属性网格将某些值显示为只读? C# 网络

C# 像在 AS3 中一样用回调函数替换

c# - 为什么要使计时器回调静态?

winforms - 控制在 Winforms 中自动完成的标签?

c# - 项目资源和本地资源图片的区别

c# - PropertyGrid 验证

c# - 字符串转换器获取标准值集合

c# - 对象不是函数错误