有人可以告诉我为什么当我尝试将文本框绑定到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分配更改为注释版本。有用。我只是不明白为什么需要包装。
谢谢!
答案 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”类的内部无法指定要绑定的接口。现有的语法参数。