c# - 将 DataSource 属性添加到自定义 WinForms 控件

标签 c# winforms data-binding

我想向我的自定义 winforms 控件添加复杂的数据绑定(bind),因此我可以执行以下操作:

myControl.DisplayMember = "Name";
myControl.ValueMember = "Name";
myControl.DataSource = new List<someObject>();

有谁知道要实现这个需要实现什么接口(interface)等?

我查看了一下,发现只有 IBindableComponent,但这似乎是针对简单绑定(bind)而不是复杂绑定(bind)。

最佳答案

根据您需要的数据绑定(bind)类型,将以下属性之一应用于您的自定义控件:

(这个问题特别提到了复杂数据绑定(bind),但给定的代码示例对我来说看起来像lookup数据绑定(bind),所以我将两者都包括在内。)

有关示例实现,请查看 .NET Framework source code :


但这些实现对我来说看起来非常复杂,因此在您自己的自定义控件中嵌入现有控件(例如 DataGridViewListBoxComboBox)可能更容易,以利用其现有数据绑定(bind)实现,而不是自己编写。 (如有必要,您可以使嵌入式控件不可见。)这是 Microsoft 在以下指南中演示的方法:

在这些指南中,他们创建了一个数据源来将自定义控件绑定(bind)到外部数据库,但看起来您只是想将自定义控件绑定(bind)到一个内部集合,例如 List<T>。 .在这种情况下,下面的改编代码可能适合您。


在 Visual Studio 的 Windows 窗体项目中,添加一个新的 UserControl .

对于复杂数据绑定(bind),应用ComplexBindingPropertiesAttribute到自定义控件。添加 DataGridView控制它。添加DataSourceDataMember属性,并将它们挂接到 DataGridView自己的属性。

// ComplexBindingControl.cs
// Adapted from https://learn.microsoft.com/visualstudio/data-tools/create-a-windows-forms-user-control-that-supports-complex-data-binding

using System.ComponentModel;
using System.Windows.Forms;

namespace BindingDemo
{
    [ComplexBindingProperties("DataSource", "DataMember")]
    public partial class ComplexBindingControl : UserControl
    {
        public ComplexBindingControl()
        {
            InitializeComponent();
        }

        // Use a DataGridView for its complex data binding implementation.

        public object DataSource
        {
            get => dataGridView1.DataSource;
            set => dataGridView1.DataSource = value;
        }

        public string DataMember
        {
            get => dataGridView1.DataMember;
            set => dataGridView1.DataMember = value;
        }
    }
}

对于查找 数据绑定(bind),应用 LookupBindingPropertiesAttribute到自定义控件。添加 ListBoxComboBox控制它。添加DataSource , DisplayMember , ValueMemberLookupMember属性,并将它们挂接到 ListBox的或ComboBox自己的属性。

// LookupBindingControl.cs
// Adapted from https://learn.microsoft.com/visualstudio/data-tools/create-a-windows-forms-user-control-that-supports-lookup-data-binding

using System.ComponentModel;
using System.Windows.Forms;

namespace BindingDemo
{
    [LookupBindingProperties("DataSource", "DisplayMember", "ValueMember", "LookupMember")]
    public partial class LookupBindingControl : UserControl
    {
        public LookupBindingControl()
        {
            InitializeComponent();
        }

        // Use a ListBox or ComboBox for its lookup data binding implementation.

        public object DataSource
        {
            get => listBox1.DataSource;
            set => listBox1.DataSource = value;
        }

        public string DisplayMember
        {
            get => listBox1.DisplayMember;
            set => listBox1.DisplayMember = value;
        }

        public string ValueMember
        {
            get => listBox1.ValueMember;
            set => listBox1.ValueMember = value;
        }

        public string LookupMember
        {
            get => listBox1.SelectedValue?.ToString();
            set => listBox1.SelectedValue = value;
        }
    }
}

(编辑:感谢 Frank's answer 提醒我 listBox1.SelectedValue 可能是 null。)

要对其进行测试,请在 Visual Studio 中构建项目,然后将自定义控件的实例添加到 Form .创建一些示例数据,并使用其相关属性将其绑定(bind)到自定义控件。

// Form1.cs

using System.Collections.Generic;
using System.Windows.Forms;

namespace BindingDemo
{
    public partial class Form1 : Form
    {
        private readonly List<SomeObject> data;

        public Form1()
        {
            InitializeComponent();

            // Prepare some sample data.
            data = new List<SomeObject>
            {
                new SomeObject("Alice"),
                new SomeObject("Bob"),
                new SomeObject("Carol"),
            };

            // Bind the data to your custom control...

            // ...for "complex" data binding:
            complexBindingControl1.DataSource = data;

            // ...for "lookup" data binding:
            lookupBindingControl1.DataSource = data;
            lookupBindingControl1.DisplayMember = "Name";
            lookupBindingControl1.ValueMember = "Name";
        }
    }

    internal class SomeObject
    {
        public SomeObject(string name)
        {
            Name = name;
        }

        public string Name { get; set; }
    }
}

关于c# - 将 DataSource 属性添加到自定义 WinForms 控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/245441/

相关文章:

wpf - 如何通过绑定(bind)在 ViewModel 中设置值?

c# - WPF ListView 以编程方式取消选择项目

c# - 将三个数组根据其索引合并为单个数组

c# - Prism WPF : Loading a User Control on Startup

c# - 为winforms中的文本框设置TextChanged事件

c# - 是否可以从另一个表单触发点击事件?

c# - 在另一个线程中打开第二个 WPF 窗口?

c# - 在事件处理程序中使用空检查

c# - 为什么我的 .NET 启动时间随着预生成的序列化程序集而增加?

JSF 与 setValueExpression 的绑定(bind)是只读的吗?