属性框PropertyGrid自定义组件

private void Form_Main_Load(object sender, Event e)
{
	PropertyMangeCus pmc = new PropertyMangeCus();
	Property pp = new Property("ID", "1", false, true);
	pp.Category = "基本信息";
	pp.DisplayName = "我的ID";
	pp.Editor = new EditorDropdownList();
	pmc.Add(pp);

    //string[] s = new string[] { "1", "2", "3", "4" };
    //Property pp = new Property("ID", "7", false, true);
    //pp.Category = "基本信息";
    //pp.DisplayName = "我的ID";
    //pp.Converter = new DropdownListConverter(s);    //Property的Converter属性就可以设置类型转换
    //pmc.Add(pp);
	
	Property pIniPath = new Property("_iniPath", "", false, true);
    pIniPath.Category = "基本信息";
    pIniPath.DisplayName = "ini路径";
    pIniPath.Editor = new PropertyFileItem();   //Property的Editor属性就可以设置属性编辑
    pmc.Add(pIniPath);
	
	propertyGrid1.SelectedObject = pmc;
}

public class Property
{
    private string _name = string.Empty;
    private object _value = null;
    private bool _readonly = false;
    private bool _visible = true;
    private string _category = string.Empty;
    private string _description = string.Empty;
    TypeConverter _converter = null;
    object _editor = null;
    private string _displayname = string.Empty;

    public Property(string sName, object sValue)
    {
        this._name = sName;
        this._value = sValue;
    }

    public Property(string sName, object sValue, bool sReadonly, bool sVisible)
    {
        this._name = sName;
        this._value = sValue;
        this._readonly = sReadonly;
        this._visible = sVisible;
    }

    public string Name          //获得属性名
    {
        get { return _name; }
        set { _name = value; }
    }

    public string Description
    {
        get { return _description; }
        set { _description = value; }
    }

    public string DisplayName   //属性显示名称
    {
        get
        {
            return _displayname;
        }
        set
        {
            _displayname = value;
        }
    }

    public TypeConverter Converter  //类型转换器,我们在制作下拉列表时需要用到
    {
        get
        {
            return _converter;
        }
        set
        {
            _converter = value;
        }
    }

    public string Category  //属性所属类别
    {
        get
        {
            return _category;
        }
        set
        {
            _category = value;
        }
    }

    public object Value  //属性值
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value;
        }
    }

    public bool ReadOnly  //是否为只读属性
    {
        get
        {
            return _readonly;
        }
        set
        {
            _readonly = value;
        }
    }

    public bool Visible  //是否可见
    {
        get
        {
            return _visible;
        }
        set
        {
            _visible = value;
        }
    }

    public virtual object Editor   //属性编辑器
    {
        get
        {
            return _editor;
        }
        set
        {
            _editor = value;
        }
    }
}

public class CustomPropertyDescriptor : PropertyDescriptor
{
    Property m_Property;
    public CustomPropertyDescriptor(ref Property myProperty, Attribute[] attrs) : base(myProperty.Name, attrs)
    {
        m_Property = myProperty;
    }

    #region PropertyDescriptor 重写方法
    public override bool CanResetValue(object component) => false;

    public override Type ComponentType => null;

    public override object GetValue(object component) => m_Property.Value;

    public override string Description => m_Property.Description.Equals("") ? m_Property.Name : m_Property.Description;

    public override string Category => m_Property.Category;

    public override string DisplayName
    {
        get
        {
            return m_Property.DisplayName != "" ? m_Property.DisplayName : m_Property.Name;
        }
    }

    public override bool IsReadOnly => m_Property.ReadOnly;

    public override void ResetValue(object component)
    {

    }

    public override bool ShouldSerializeValue(object component) => false;

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

    public override TypeConverter Converter => m_Property.Converter;

    public override Type PropertyType => m_Property.Value.GetType();

    public override object GetEditor(Type editorBaseType)
    {
        return m_Property.Editor == null ? base.GetEditor(editorBaseType) : m_Property.Editor;
    }

    #endregion
}

public class PropertyMangeCls:CollectionBase, ICustomTypeDescriptor
{
    public void Add(Property value)
    {
        int flag = -1;
        if(value != null)
        {
            if(base.List.Count > 0)
            {
                IList<Property> mList = new List<Property>();
                for (int i = 0; i < base.List.Count; i++)
                {
                    Property p = base.List[i] as Property;
                    if(value.Name == p.Name)
                    {
                        flag = i;
                    }
                    mList.Add(p);
                }
                if(flag == -1)
                {
                    mList.Add(value);
                }
                base.List.Clear();
                foreach(Property p in mList)
                {
                    base.List.Add(p);
                }
            }
            else
            {
                base.List.Add(value);
            }
        }
    }

    public void Remove(Property value)
    {
        if(value != null && base.List.Count > 0)
        {
            base.List.Remove(value);
        }
    }

    public Property this[int index]
    {
        get
        {
            return (Property)base.List[index];
        }

        set
        {
            base.List[index] = (Property)value;
        }
    }

    #region ICustomTypeDescriptor 成员

    public object GetPropertyOwner(PropertyDescriptor pd) => this;

    public string GetClassName() => TypeDescriptor.GetClassName(this, true);

    public string GetComponentName() => TypeDescriptor.GetComponentName(this, true);

    public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(this, true);

    public TypeConverter GetConverter() => TypeDescriptor.GetConverter(this, true);

    public object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(this, editorBaseType, true);

    public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this, true);

    public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(this, true);

    public EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(this, attributes, true);

    public PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this, true);

    public PropertyDescriptorCollection GetProperties() => TypeDescriptor.GetProperties(this, true);

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

    #endregion
}

下拉框


public class EditorDropdownList : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.DropDown;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        if(editorService != null)
        {
            ListBox lb = new ListBox();
            lb.Items.Add("1");
            lb.Items.Add("2");
            lb.Items.Add("3");
            lb.Items.Add("4");
            lb.Items.Add("5");
            lb.Items.Add("6");
            lb.SelectedIndexChanged += new System.EventHandler(lb_Click);
            editorService.DropDownControl(lb);
            value = lb.SelectedItem;
        }
        return base.EditValue(context, provider, value);
    }

    private void lb_Click(Object sender, EventArgs args)
    {
        ListBox lb = (ListBox)sender;
        Form fm = lb.FindForm();
        fm.Close();
    }
}

文件选择器

public class PropertyFileItem:FileNameEditor
{
    protected override void InitializeDialog(OpenFileDialog openFileDialog)
    {
        base.InitializeDialog(openFileDialog);
        openFileDialog.Filter = "ini文件|*.ini";
    }
}

文件选择器2

public class PropertyFileItem1:UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        if(edSvc != null)
        {
            //可以打开任何特定的对话框
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "ini(*.ini)|*.ini";
            dialog.AddExtension = false;
            if (dialog.ShowDialog().Equals(DialogResult.OK))
                return dialog.FileName;
        }
        return value;
    }
}

类型转换器

public class DropdownListConverter:StringConverter
{
    object[] m_Objects;
    public DropdownListConverter(object[] objects)
    {
        m_Objects = objects;
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;    //true 下拉框不可编辑
    }

    public override
    System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(m_Objects); //我们可以直接在内部定义一个数组,但并不建议这样做,这样对于下拉框的灵活性有很大影响
    }
}

代码主要参考如下文章,在此特意感谢两位分享。

  1. C#自定义PropertyGrid属性
  2. .NET控件开发基础(一)控件设计时支持方式之UITypeEditor
属性网格(System.Windows.Forms.PropertyGrid)是一个用于显示和编辑对象属性的控件。下面是一个简单的代码示例,展示如何创建一个PropertyGrid并绑定到一个自定义的对象: ```csharp using System; using System.Windows.Forms; public class MyClass // 自定义一个类 { public string Name { get; set; } public int Age { get; set; } } public partial class Form1 : Form { private MyClass myObject; public Form1() { InitializeComponent(); // 创建一个MyClass实例 myObject = new MyClass(); myObject.Name = "John"; myObject.Age = 30; // 初始化PropertyGrid,添加需要展示的属性 propertyGrid1.SelectedObject = myObject; propertyGrid1.Properties.Add("Name", myObject.GetType().GetProperty("Name")); propertyGrid1.Properties.Add("Age", myObject.GetType().GetProperty("Age")); // 当属性发生变化时,更新UI propertyGrid1.PropertyValueChanged += PropertyGrid_PropertyValueChanged; } void PropertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e) { if (e(PropertyGrid1.SelectedObject).PropertyInfo.Name == "Name" || e(PropertyGrid1.SelectedObject).PropertyInfo.Name == "Age") { Console.WriteLine($"'{e.PropertyDescriptor.Name}' 的新值:{e.NewValue}"); } } // Form的加载事件 private void Form1_Load(object sender, EventArgs e) { // 展示Form Show(); } } ``` 在这个例子中,我们首先创建了一个`MyClass`实例,并将其绑定到PropertyGrid的`SelectedObject`属性上。然后,我们通过`Properties.Add()`方法手动将类的属性添加到PropertyGrid中。当用户在属性网格修改了属性时,`PropertyValueChanged`事件会被触发,我们可以在此处理程序中获取新的属性值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值