将Windows窗体绑定到SqlConnectionStringBuilder

时间:2017-03-09 23:03:25

标签: c# winforms data-binding

有人可以告诉我为什么当我尝试将文本框绑定到SqlConnectionStringBuilder实例时它不起作用而且我收到错误。

"无法绑定到DataSource上的属性或列DataSource。\ r \ n \ nParameter name:dataMember"

似乎绑定管理器在反映找到它时无法找到该属性。

如果我写一个'什么都不做'只是转发get / set操作的包装器按预期工作。

我反映了SqlConnectionStringBuilder对象,并没有看到任何会让我认为我无法直接绑定到它的属性的东西。

这是我使用...

代码的模拟
public partial class frmMain : Form {

    private BindingSource bindingSource = new BindingSource();

    public frmMain() {
        InitializeComponent();

        //bindingSource.DataSource = typeof(SqlConnectionStringBuilderWrapper);
        bindingSource.DataSource = typeof(SqlConnectionStringBuilder);

        tbDataSource.DataBindings.Add("Text", bindingSource, "DataSource");

        initializeConnectionStrings();
    }

    private void initializeConnectionStrings() {
        SqlConnectionStringBuilder defaultBuilder = null;
        cmbConnectionStrings.DataSource = SqlConnectionStrings.ConnectionBuilders(out defaultBuilder);

        //bindingSource.DataSource = new SqlConnectionStringBuilderWrapper(defaultBuilder);
        bindingSource.DataSource = defaultBuilder;

        cmbConnectionStrings.SelectedItem = defaultBuilder;
    }
}

public class SqlConnectionStringBuilderWrapper : INotifyPropertyChanged {private SqlConnectionStringBuilder builder = null;

    public SqlConnectionStringBuilderWrapper(SqlConnectionStringBuilder builder) { this.builder = builder; }
    public SqlConnectionStringBuilder Builder { get { return builder; } set {} }

    public string DataSource {
        get { return builder.DataSource; }
        set {
            if (builder.DataSource != value) {
                builder.DataSource = value;
                OnPropertyChanged("DataSource");
            }
        }
    }
...
}

如果我将DataSource分配更改为注释版本。有用。我只是不明白为什么需要包装。

谢谢!

1 个答案:

答案 0 :(得分:0)

长时间读者,第一次发帖。这就是......

设置阶段:

•SqlConnectionStringBuilder继承自DbConnectionStringBuilder

•DbConnectionStringBuilder实现接口:IDictionary,ICollection,IEnumerable和ICustomTypeDescription

这些接口在类上的使用是“奇怪的”...意味着没有连接字符串的集合(只有一个)。这些接口的用法是管理“DataSource / ConnectionString”属性中字符串元素的键/值对。

当您创建实现INotifyPropertyChanged的包装器时,您的示例工作的原因是因为BindingSource知道如何从INotifyPropertyChanged接口获取而不会混淆IDictionary / ICollection / IEnumerable / ICustomTypeDescription的派生类实现(您绑定的IE一个只实现一个接口INotifyPropertyChanged的具体类。除了你的解决方法,我认为另一种方法是使用SqlConnection类(它没有关联的集合接口)。

关于绑定源类内部的最佳深度帖子是这篇博客:https://www.codeproject.com/Articles/24656/A-Detailed-Data-Binding-Tutorial。查看“它是如何工作的?”部分。在阅读完之后我停止追求绑定源的内部工作方式,并且会做一些魔术臂挥手说问题#1在那个混乱中的某个地方:P

问题#1 我无法实现INotifyPropertyChanged接口和任何IDictionary / ICollection / IEnumerable / ICustomTypeDescription,并使用“bindingSource”来绑定类上的非集合类型属性(特定于字符串)。在您的情况下,这是“DataSource”属性,它是一个字符串而不是“集合”类型。

我创建了一个示例类,它实现了INotifyPropertyChanged和其他任何接口(IDictionary / ICollection / IEnumerable / ICustomTypeDescription)。绑定从未使用Textblock.Text绑定工作到单个属性。对于试图这样做的人以及它为什么会失败,我找不到任何结果......显然没有人试图将INotifyPropertyChanged与任何其他受支持的可绑定接口一起实现...... https://docs.microsoft.com/en-us/dotnet/framework/winforms/interfaces-related-to-data-binding。当尝试在实现多个可用/有效接口类型的类上使用bindingSource时,文档很稀疏。

问题#2 BindingSource对象无法在派生类上查看父类的继承属性。虽然不是问题的根本原因,但派生的SqlConnectionStringBuilder会使情况复杂化。

最佳解释:Why BindingSource component cannot see inherited properties? 看起来Microsoft已确认此问题并关闭了功能请求:https://connect.microsoft.com/VisualStudio/feedback/details/431273/interface-inheritance-bug 其他信息:Winforms databinding with interface inheritance 上面最后一个链接中提供的最佳逻辑原因 - “接口支持多重继承,但类不支持。”

虽然这与你的问题没有直接关系,但我认为问题#1是一个类似的缺陷,问题是“BindingSource”类的内部无法指定要绑定的接口。现有的语法参数。