Binding textboxes to properties of a comboBox.SelectedItem
I'm using winforms and I've got a comboBox that represents an IQueryable. Below the combobox is a series of textboxes that I would like to be bound to the currently selected from the combo box.
Here is my code.
public partial class TestForm : Form
{
public DataClassesDataContext DataContext;
public IQueryable<T> datasource;
// Ctor
public TestForm()
{
InitializeComponent();
// L2S data context
this.DataContext = new DataClassesDataContext();
// Get the variable for the data source
this.datasource = this.DataContext.Ts;
// setup the binding for the combobox
this.comboBox1.DataSource = this.datasource;
this.comboBox1.DisplayMember = "Description";
this.comboBox1.ValueMember = "Id";
// assign the databindings of the text boxes to the selectedItem of the combo box
// this is where the problem is, afaik
TId.Data开发者_如何学GoBindings.Add(new Binding("Text", this.comboBox1.SelectedItem, "Id"));
TUser.DataBindings.Add(new Binding("Text", this.comboBox1.SelectedItem, "User"));
TDescription.DataBindings.Add(new Binding("Text", this.comboBox1.SelectedItem, "Description"));
}
Doing this binds everything, When I change the values in the text boxes, it updates the initially selected item in the combo box just fine. Even when I change the description, it updates the displayed text in the drop don, all that is great.
However, when I select a different item from the drop down, the text boxes don't bind to that newly selected item, they stay bound to the old one.
Do I need to remove and re-add my bindings every time the selection changes on the combo box?
My original answer was wrong, and admittedly I do not fully understand what all is happening here, but I have a solution which is working.
Basically you need to grab the BindingManagerBase
from the BindingContext
and use it to enforce databinding on each SelectedItemChanged
event.
public partial class TestForm : Form
{
public DataClassesDataContext DataContext;
public IQueryable<T> datasource;
private BindingManagerBase bmComboBoxSelectedItem;
// Ctor
public TestForm()
{
InitializeComponent();
// L2S data context
this.DataContext = new DataClassesDataContext();
// Get the variable for the data source
this.datasource = this.DataContext.Ts;
// setup the binding for the combobox
this.comboBox1.DataSource = this.datasource;
this.comboBox1.DisplayMember = "Description";
this.comboBox1.ValueMember = "Id";
// assign the databindings of the text boxes to the selectedItem of the combo box
// this is where the problem is, afaik
TId.DataBindings.Add(new Binding("Text", this.comboBox1, "SelectedItem.Id"));
TUser.DataBindings.Add(new Binding("Text", this.comboBox1, "SelectedItem.User"));
TDescription.DataBindings.Add(new Binding("Text", this.comboBox1, "SelectedItem.Description"));
bmComboBoxSelectedItem = this.BindingContext[this.comboBox1, "SelectedItem"];
}
// make sure you assign this event on the forms designer or your preferred method
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
bmCustomers.ResumeBinding();
}
}
This MSDN article helped a lot.
Use a BindingSource rather than directly relying upon the L2S data context. The binding source uses a concurrency manager to handle all the updating for you and the L2S does not
Working code:
public partial class TestForm : Form
{
public DataClassesDataContext DataContext;
// Incorrect: public IQueryable<T> datasource;
// Correct:
public BindingSource TsDataSource;
// Ctor
public TestForm()
{
InitializeComponent();
// L2S data context
this.DataContext = new DataClassesDataContext();
// Get the variable for the data source
// Incorrect: this.datasource = this.DataContext.Ts;
// Correct:
this.TsDataSource = new BindingSource();
this.TsDataSource.DataSource = this.DataContext.Ts;
// setup the binding for the combobox
this.comboBox1.DataSource = this.TsDataSource;
this.comboBox1.DisplayMember = "Description";
this.comboBox1.ValueMember = "Id";
// assign the databindings of the text boxes to the selectedItem of the combo box
TId.DataBindings.Add(new Binding("Text", this.TsDataSource, "Id"));
TUser.DataBindings.Add(new Binding("Text", this.TsDataSource, "User"));
TDescription.DataBindings.Add(new Binding("Text", this.TsDataSource, "Description"));
}
More about BindingSource from the source (couldnt resist):
The BindingSource component serves many purposes. First, it simplifies binding controls on a form to data by providing currency management, change notification, and other services between Windows Forms controls and data sources. This is accomplished by attaching the BindingSource component to your data source using the DataSource property. For complex binding scenarios you can optionally set the DataMember property to a specific column or list in the data source. You then bind controls to the BindingSource. All further interaction with the data is accomplished with calls to the BindingSource component. For examples on how the BindingSource can simplify the binding process, see How to: Bind Windows Forms Controls to DBNull Database Values and How to: Handle Errors and Exceptions that Occur with Databinding. Navigation and updating of the data source is accomplished through methods such as MoveNext, MoveLast, and Remove. Operations such as sorting and filtering are handled through the Sort and Filter properties. For more information on using sorting and filtering with the BindingSource, see How to: Sort and Filter ADO.NET Data with the Windows Forms BindingSource Component.
精彩评论