使Propertygrid在运行时显示绑定属性符号

时间:2018-01-16 00:40:59

标签: c# winforms data-binding windows-forms-designer propertygrid

使用DataBindings将控件的属性绑定到数据源时,属性网格将在该属性相应的网格项中显示一个小的紫色或黑色符号。

即使将PropertyGrid放在窗体上并将其SelectedObject属性设置为带有bound属性的控件,表单上的PropertyGrid也会显示该符号。

但仅限于设计时。

是否有(简单)方法使同一个PropertyGrid在运行时显示此符号?

1 个答案:

答案 0 :(得分:2)

它由Visual Studio设计师内部事务处理。但您也可以将此功能添加到PropertyGrid

enter image description here

您需要实现IPropertyValueUIService并使用反射,将服务实例分配给应显示字形的网格条目。此实现有一个方法GetPropertyUIValueItems,可用于提供该字形和工具提示,以显示PropertyGrid中属性标签附近。这些值将用于属性网格条目的PaintLabel方法。

然后创建一个继承的PropertyGrid并覆盖OnSelectedObjectsChangedOnPropertySortChanged。在每个属性网格条目项的方法中,该项目呈现数据绑定集合中的属性,将实现的IPropertyValueUIService的实例设置为pvSvc的{​​{1}}私有属性的值,并且附加一个事件处理程序,当PropertyGrid请求有关该属性的其他信息时将调用该事件处理程序。通过使用PropertyGrid附加事件处理程序,您可以返回要在属性前显示的工具提示和图像。

示例

您可以在此处下载完整示例:

您可以按如下方式找到实施的主要类别。

PropertyValueUIService

GetPropertyUIValueItems

ExPropertyGrid

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;

namespace PropertyGridDataBindingGlyph
{
    public class PropertyValueUIService : IPropertyValueUIService
    {
        private PropertyValueUIHandler handler;
        private ArrayList items;

        public event EventHandler PropertyUIValueItemsChanged;
        public void NotifyPropertyValueUIItemsChanged()
        {
            PropertyUIValueItemsChanged?.Invoke(this, EventArgs.Empty);
        }
        public void AddPropertyValueUIHandler(PropertyValueUIHandler newHandler)
        {
            handler += newHandler ?? throw new ArgumentNullException("newHandler");
        }
        public PropertyValueUIItem[] GetPropertyUIValueItems(ITypeDescriptorContext context, PropertyDescriptor propDesc)
        {
            if (propDesc == null)
                throw new ArgumentNullException("propDesc");
            if (this.handler == null)
                return new PropertyValueUIItem[0];
            lock (this)
            {
                if (this.items == null)
                    this.items = new ArrayList();
                this.handler(context, propDesc, this.items);
                int count = this.items.Count;
                if (count > 0)
                {
                    PropertyValueUIItem[] propertyValueUiItemArray = new PropertyValueUIItem[count];
                    this.items.CopyTo((Array)propertyValueUiItemArray, 0);
                    this.items.Clear();
                    return propertyValueUiItemArray;
                }
            }
            return null;
        }
        public void RemovePropertyValueUIHandler(PropertyValueUIHandler newHandler)
        {
            handler -= newHandler ?? throw new ArgumentNullException("newHandler");

        }
    }
}