我创建了一个带数据绑定的简单示例(遗憾的是我们的系统中有类似的情况)。我创建了一个时髦的组合框:
public class FunkyComboBox : ComboBox
{
private object currentValue = null;
public FunkyComboBox()
{
if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
this.Items.Add("Other...");
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (!this.Text.StartsWith("Other") && currentValue != this.SelectedItem)
{
currentValue = this.SelectedItem;
BindingManagerBase bindingManager = DataManager;
base.OnSelectedIndexChanged(e);
}
}
protected override void OnSelectionChangeCommitted(EventArgs e)
{
string itemAsStr = this.SelectedItem != null ? SelectedItem.ToString() : "";
if (itemAsStr.StartsWith("Other"))
{
string newItem = "item" + this.Items.Count;
if (!Items.Contains(newItem))
{
Items.Add(newItem);
}
SelectedItem = newItem;
}
else
{
OnSelectedIndexChanged(e); //forces a selectedIndexChanged event to be thrown
base.OnSelectionChangeCommitted(e);
}
}
}
当您单击其他时,会添加新项目(在我们的系统中,它会打开一个可以查询数据库的表单等)。然后我有一个简单的数据对象:
public class MyClass
{
private string value;
public string MyData
{
get{ return value;}
set{ this.value = value;}
}
}
一个带有两个控件的测试表单绑定到此对象(删除了一些设计器代码):
public partial class Form1 : Form
{
MyClass myObj = new MyClass();
public Form1()
{
InitializeComponent();
myObj.MyData = "Nothing";
myClassBindingSource.DataSource = myObj;
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.textBox1 = new System.Windows.Forms.TextBox();
this.myClassBindingSource = new System.Windows.Forms.BindingSource(this.components);
this.funkyComboBox1 = new DataBindingTests.FunkyComboBox();
((System.ComponentModel.ISupportInitialize)(this.myClassBindingSource)).BeginInit();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
//
// myClassBindingSource
//
this.myClassBindingSource.DataSource = typeof(DataBindingTests.MyClass);
//
// funkyComboBox1
//
this.funkyComboBox1.DataBindings.Add(new System.Windows.Forms.Binding("SelectedItem", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.funkyComboBox1.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
//
// Form1
//
this.Controls.Add(this.textBox1);
this.Controls.Add(this.funkyComboBox1);
((System.ComponentModel.ISupportInitialize)(this.myClassBindingSource)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
private FunkyComboBox funkyComboBox1;
private System.Windows.Forms.BindingSource myClassBindingSource;
private System.Windows.Forms.TextBox textBox1;
}
如果您运行此代码并开始使用组合框,您会注意到编辑框只有在您单击它时才会更改。每次更改后,都会将空值设置为我的对象,并清除文本框。如何在每次更改后设置正确的值?
答案 0 :(得分:2)
我不确定为什么ComboBox数据绑定会以这种方式运行,但我找到了一种解决方法。如果您没有为ComboBox的值使用数据源,似乎数据绑定无法正常工作。
我对FunkyComboBox做了一些小改动,现在按预期工作了。
public class FunkyComboBox : ComboBox
{
private object currentValue = null;
private List<string> innerItems = new List<string>();
public FunkyComboBox()
{
if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
innerItems.Add("Other...");
this.DataSource = innerItems;
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (!this.Text.StartsWith("Other") && currentValue != this.SelectedItem)
{
currentValue = this.SelectedItem;
BindingManagerBase bindingManager = DataManager;
base.OnSelectedIndexChanged(e);
}
}
protected override void OnSelectionChangeCommitted(EventArgs e)
{
string itemAsStr = this.SelectedItem != null ? SelectedItem.ToString() : "";
if (itemAsStr.StartsWith("Other"))
{
string newItem = "item" + this.Items.Count;
if(!innerItems.Contains(newItem))
{
innerItems.Add(newItem);
this.RefreshItems();
} SelectedItem = newItem;
}
else
{
OnSelectedIndexChanged(e);
//forces a selectedIndexChanged event to be thrown
base.OnSelectionChangeCommitted(e);
}
}
}
答案 1 :(得分:0)
它似乎也是基本ComboBox的一个错误。不可能使这种绑定源疯狂正常工作。