不带属性的WinForms数据绑定

问题描述 投票:0回答:1

在 WinForms 中,是否可以在不使用属性的情况下进行数据绑定?

我有一个类,它具有一些可以数据绑定的属性,但它也有一些用户定义的自定义字段,这些字段仅在运行时可用。例如:

public class Item
{
    public int Id { get; set; } // I can databind controls to this
    public string Name { get; set; } // I can databind controls to this

    public object GetCustomFieldValue(string customFieldName);
    public void SetCustomFieldValue(string customFieldName, object value);
}

有没有办法挂钩绑定逻辑来调用 GetCustomFieldValue 和 SetCustomFieldValue 方法而不是获取/设置属性?

我尝试创建一个继承自 Binding 的自定义绑定类,希望重写某些方法,例如 ReadValue() 和 WriteValue(),但它们不是虚拟的,因此看起来像是死胡同。

还有其他我可以尝试的方法吗?

c# .net winforms data-binding
1个回答
0
投票

这是我最终想出的解决方案。

为您的自定义字段创建界面:

public interface ICustomFields
{
    Dictionary<string, object> CustomFields { get; }
}

确保具有自定义字段的类实现该接口:

public class Item : ICustomFields
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Dictionary<string, object> CustomFields { get; set; } = new Dictionary<string, object>();
}

最后,我创建了一个扩展方法来简化添加数据绑定:

public static void AddCustomFieldBinding(this ControlBindingsCollection bindings, string controlPropertyName, object dataSource, string customFieldName)
{
    Binding binding = new Binding(controlPropertyName, dataSource, null);
    binding.Format += (o, c) => c.Value = ((ICustomFields)c.Value).CustomFields[customFieldName];

    binding.Parse += (o, c) =>
    {
        Binding b = (Binding)o;
        BindingSource bs = (BindingSource)b.DataSource;
        ICustomFields i = (ICustomFields)bs.Current;
        i.CustomFields[customFieldName] = c.Value;
    };

    bindings.Add(binding);
}

然后假设您有一个带有 BindingSource 的表单和一个要绑定数据的 TextBox 控件,您可以在表单的 Load 事件中使用上面的代码:

private void MainForm_Load(object sender, EventArgs e)
{
    // Create an example Item with an additional custom field called "Notes"
    Item item = new Item() { Id = 1, Name = "Example item" };
    item.CustomFields["Notes"] = "Example notes";

    // Add the custom data binding using the extension method
    this.notesTextBox.DataBindings.AddCustomFieldBinding("Text", this.itemBindingSource, "Notes");

    this.itemBindingSource.DataSource = item;
}
© www.soinside.com 2019 - 2024. All rights reserved.