PropertyGrid自定义控件使用详解

标题:PropertyGrid自定义控件使用详解

简介

PropertyGrid 是 Windows 系统中提供的一个用于显示和编辑对象属性的控件。该控件提供了良好的可扩展性,我们可以通过自定义控件来实现需求,本文将详细讲解如何使用 PropertyGrid 自定义控件。

步骤说明

步骤一:新建自定义控件

开发环境为 Visual Studio 2019。

  1. 在解决方案资源管理器中,右键单击项目,选择“添加”-“类”。

  2. 在“名称”文本框中输入自定义控件的类名。

  3. 勾选“从 User Control 派生”。

  4. 单击添加按钮。

  5. 在自定义控件的设计器中,以需要的方式添加控件。

步骤二:继承 UITypeEditorTypeConverter

接下来我们需要继承 UITypeEditorTypeConverter 类使 PropertyGrid 能够正常显示和编辑自定义控件。

public class CustomControlEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        // 指定显示编辑器的样式
        return UITypeEditorEditStyle.DropDowm;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        // 显示自定义控件的窗口
        CustomControlDlg dlg = new CustomControlDlg(value as CustomControl);

        if (dlg.ShowDialog() == DialogResult.OK)
        {
            // 返回自定义控件的实例
            return dlg.CustomControl;
        }

        // 返回原值
        return value;
    }
}

public class CustomControlConverter : ExpandableObjectConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        // 判断 destinationType 是否能够转换为字符串类型
        if (destinationType == typeof(string))
        {
            return true;
        }

        return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        // 如果 destinationType 能够转换为字符串类型,返回自定义控件的名称
        if (destinationType == typeof(string))
        {
            CustomControl customControl = value as CustomControl;
            if (customControl != null)
            {
                return customControl.Name;
            }
        }

        return base.ConvertTo(context, culture, value, destinationType);
    }
}

在上述代码中,CustomControlEditor 类指定了编辑器的样式,并且在 EditValue 函数中显示了自定义控件的窗口,返回该控件的实例。CustomControlConverter 类继承了 ExpandableObjectConverter,重载了 CanConvertToConvertTo 函数,能够将自定义控件转换为字符串类型并在显示时正常显示。

步骤三:为属性添加自定义控件

设置步骤完成后,我们需要为一个属性关联自定义控件。

  1. 在类的代码中定义需要关联的属性。
[Editor(typeof(CustomControlEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(CustomControlConverter))]
public CustomControl CustomControlProperty { get; set; }
  1. 在使用 PropertyGrid 的窗体中,设置该属性的默认值。
private void Form1_Load(object sender, EventArgs e)
{
    CustomControlControl customControl = new CustomControlControl();
    propertyGrid1.SelectedObject = new
    {
        CustomControlProperty = customControl
    };
}

实例说明

示例 1:自定义按钮

在下面的示例中,我们将在自定义控件中实现一个简单的按钮。

  1. 在自定义控件中添加一个按钮。

  2. 在自定义控件的代码中添加事件处理函数。

private void button1_Click(object sender, System.EventArgs e)
{
    // 在控制台输出
    Console.WriteLine("Clicked");
}
  1. CustomControlEditor 类的 EditValue 函数中,将自定义控件的窗口传递给自定义控件类(CustomControlControl),并订阅 ButtonClicked 事件。
CustomControlDlg dlg = new CustomControlDlg(value as CustomControlControl);
dlg.CustomControlControl.ButtonClicked += CustomControl_ButtonClicked;

private void CustomControl_ButtonClicked(object sender, EventArgs e)
{
    // 获取控件并调用按钮的事件处理函数
    (sender as CustomControlControl).button1.PerformClick();
}
  1. 在自定义控件的 UserControl 中添加一个自定义事件,用于触发按钮事件。
public event EventHandler ButtonClicked;
  1. 属性关联自定义控件。
[Editor(typeof(CustomControlEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(CustomControlConverter))]
public CustomControlControl CustomControlProperty { get; set; }
  1. 在使用 PropertyGrid 的窗体中,设置该属性的默认值。
private void Form1_Load(object sender, EventArgs e)
{
    propertyGrid1.SelectedObject = new
    {
        CustomControlProperty = new CustomControlControl()
    };
}

示例 2:自定义字典

在下面的示例中,我们将在自定义控件中实现一个简单的字典。

  1. 在自定义控件中添加一个 TextBox 和一个 Button,并设置相应的事件处理函数。
private Dictionary<string, string> dictionary = new Dictionary<string, string>();

private void button1_Click(object sender, EventArgs e)
{
    // 添加键值对到字典中
    dictionary.Add(textBox1.Text, textBox2.Text);

    // 清空输入框
    textBox1.Text = "";
    textBox2.Text = "";

    // 刷新列表
    ListBox listBox = (ListBox)Controls["listBox1"];
    listBox.DataSource = dictionary.ToList();
    listBox.DisplayMember = "Key";
}

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    // 根据当前选择更新文本框中内容
    ListBox listBox = sender as ListBox;
    if (listBox.SelectedIndex >= 0)
    {
        textBox1.Text = ((KeyValuePair<string, string>)listBox.SelectedItem).Key;
        textBox2.Text = ((KeyValuePair<string, string>)listBox.SelectedItem).Value;
    }
}

private void textBox_TextChanged(object sender, EventArgs e)
{
    // 更新字典中键值对
    ListBox listBox = (ListBox)Controls["listBox1"];

    KeyValuePair<string, string> selectedKeyValuePair = (KeyValuePair<string, string>)listBox.SelectedItem;
    int selectedIndex = listBox.SelectedIndex;

    if (selectedIndex >= 0)
    {
        string key = textBox1.Text;
        string value = textBox2.Text;
        dictionary.Remove(selectedKeyValuePair.Key);
        dictionary.Add(key, value);

        listBox.DataSource = dictionary.ToList();
        listBox.SelectedIndex = selectedIndex;
    }
}
  1. CustomControlEditor 类的 EditValue 函数中,将自定义控件的窗口传递给自定义控件类(CustomControlDict),设置 dictionary 的值,并进行数据绑定。
CustomControlDlg dlg = new CustomControlDlg(value as CustomControlDict);
CustomControlDict customControlDict = dlg.CustomControlDict;

foreach (KeyValuePair<string, string> kvp in customControlDict.dictionary)
{
    customControlDict.listBox.Items.Add(kvp);
}

customControlDict.bindingSource.DataSource = customControlDict.dictionary;
customControlDict.listBox.DataSource = customControlDict.bindingSource;
customControlDict.listBox.ValueMember = "Key";
customControlDict.listBox.SelectedIndexChanged += customControlDict.listBox1_SelectedIndexChanged;
customControlDict.keyTextBox.TextChanged += customControlDict.textBox_TextChanged;
customControlDict.valueTextBox.TextChanged += customControlDict.textBox_TextChanged;

if (dlg.ShowDialog() == DialogResult.OK)
{
    return customControlDict;
}
  1. 在自定义控件的代码中,增加以下代码。
public Dictionary<string, string> dictionary = new Dictionary<string, string>();

private void okButton_Click(object sender, EventArgs e)
{
    Close(DialogResult.OK);
}

private void cancelButton_Click(object sender, EventArgs e)
{
    Close(DialogResult.Cancel);
}
  1. 在自定义控件的代码中,添加一个 BindingSource 和一个 ListBox,并注册相应的事件处理函数。
public BindingSource bindingSource = new BindingSource();
public ListBox listBox = new ListBox();

public CustomControlDict()
{
    InitializeComponent();
    Controls.Add(listBox);

    listBox.Location = new Point(keyTextBox.Left, keyTextBox.Bottom + 10);
    listBox.Width = keyTextBox.Width + valueTextBox.Width + 1;
    listBox.Height = okButton.Top - listBox.Top - 10;
    listBox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right;

    listBox.SelectedIndexChanged += listBox1_SelectedIndexChanged;

    bindingNavigator1.BindingSource = bindingSource;
    listBox.DisplayMember = "Key";
    listBox.ValueMember = "Value";

    Controls.Add(bindingNavigator1);
    bindingNavigator1.Location = new Point(keyTextBox.Left, listBox.Bottom + 10);

    bindingNavigator1.Visible = false;
}

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    KeyValuePair<string, string> item = (KeyValuePair<string, string>)listBox.SelectedItem;
    keyTextBox.Text = item.Key;
    valueTextBox.Text = item.Value;
}
  1. 属性关联自定义控件。
[Editor(typeof(CustomControlEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(CustomControlConverter))]
public CustomControlDict CustomControlProperty { get; set; }
  1. 在使用 PropertyGrid 的窗体中,设置该属性的默认值。
private void Form1_Load(object sender, EventArgs e)
{
    CustomControlDict customControlDict = new CustomControlDict();
    customControlDict.dictionary.Add("key1", "value1");
    customControlDict.dictionary.Add("key2", "value2");

    propertyGrid1.SelectedObject = new
    {
        CustomControlProperty = customControlDict
    };
}

结束语

在本文中,我们详细讲解了如何使用 PropertyGrid 自定义控件。通过实现自定义控件,我们可以更灵活地满足不同的需求。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PropertyGrid自定义控件使用详解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • lambdaQueryWrapper多条件嵌套查询方式

    lambdaQueryWrapper多条件嵌套查询方式攻略 lambdaQueryWrapper是MyBatis-Plus框架中的一个查询构造器,它提供了一种方便的方式来构建复杂的查询条件。其中,多条件嵌套查询方式允许我们在查询中嵌套多个条件,以实现更加灵活和精确的查询。 下面是使用lambdaQueryWrapper多条件嵌套查询方式的完整攻略,包括示例说…

    other 2023年7月28日
    00
  • C++实现字符串切割的两种方法

    C++实现字符串切割的两种方法 在C++中,经常需要将字符串按照指定的分隔符进行切割,得到分割后的子字符串。本文将会介绍两种实现字符串切割的方法。 方法一:使用STL库中的stringstream 在C++中,STL库中的stringstream类可以方便地将字符串转换为其他数据类型,同时也能够按照指定的分隔符对字符串进行切割。具体的实现方法如下: #inc…

    other 2023年6月20日
    00
  • 鼠标右键失灵怎么解决? 重装系统后鼠标失灵的解决办法

    鼠标右键失灵怎么解决? 一、确认鼠标硬件问题 首先需要确认一下鼠标硬件是否出现了故障,可以将鼠标连接到另一台电脑或者笔记本电脑上试试。如果在其他电脑或笔记本电脑上鼠标工作正常,那么极有可能出现问题的是电脑系统设置或软件驱动的问题。 二、关注鼠标设置 接下来,可以在控制面板中调整鼠标设置,以检查是否出现了模拟器或指针设置的问题,这些问题可能会导致鼠标失灵或鼠标…

    other 2023年6月27日
    00
  • 使用vue3+ts+setup获取全局变量getCurrentInstance的方法实例

    当使用Vue 3与TypeScript(TS)结合时,可以通过setup函数获取全局变量getCurrentInstance。getCurrentInstance是Vue 3中的一个函数,用于获取当前组件实例的引用。下面是使用Vue 3 + TS + setup函数获取getCurrentInstance的方法实例的完整攻略: 首先,确保你已经安装了Vue …

    other 2023年7月29日
    00
  • 百度蜘蛛是抓取网站和提高抓取频率的技巧分享

    下面我来详细讲解一下“百度蜘蛛是抓取网站和提高抓取频率的技巧分享”的完整攻略。 什么是百度蜘蛛? 百度蜘蛛是百度搜索引擎的爬虫程序,也叫做Baidu Spider(以下简称“蜘蛛”)。蜘蛛按照一定的规则和算法,自动地访问网页、收集网页内容和链接,进而生成网页索引并提供给用户搜索结果。 如何让百度蜘蛛更好地抓取网站? 1. 提高网站的可访问性 蜘蛛需要能够访问…

    other 2023年6月27日
    00
  • Mac强制关机重启的方法以及危害

    标题:Mac强制关机重启的方法以及危害 强制关机的方法 在Mac上,通常我们使用关闭软件或按下电源键的方式来关机。但是,如果你的Mac没有响应或者卡住了,这时候只能通过强制关机来解决,下面是具体的步骤: 长按电源键:在你的Mac没有响应的情况下,按住电源键大约5秒钟,直到屏幕变暗并且没有反应。 拔掉电源线:如果长按电源键没有反应,还可以拔掉电源线来强制关闭电…

    other 2023年6月27日
    00
  • C++ COM编程之接口背后的虚函数表

    C++ COM编程之接口背后的虚函数表 什么是虚函数表? 虚函数表(Virtual Function Table,简称 vtable)是 C++ 语言中实现动态多态(Runtime Polymorphism)的机制之一。每个类在其对象之中都有一个虚函数表,用于实现在多态情况下的函数调用。 什么是COM接口? Component Object Model(简称…

    other 2023年6月26日
    00
  • iOS12 beta2怎么升级 苹果ios12开发者预览版beta2更新升级图文教程

    iOS12 beta2怎么升级 苹果ios12开发者预览版beta2更新升级图文教程 前言 苹果在 WWDC 2018 上发布了最新的 iOS 12 系统,并随之推出了开发者预览版 beta1。现在,苹果已经正式发布了开发者预览版 beta2,并且相信很多开发者和比较关注苹果系统的用户都非常想要体验新版系统所带来的新功能和优化。那么,本篇文章将为大家详细讲解…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部