How to maintain ComboBox.SelectedItem reference when DataSource is resorted?

Posted by Dave on Stack Overflow See other posts from Stack Overflow or by Dave
Published on 2010-03-12T16:58:10Z Indexed on 2010/03/12 17:27 UTC
Read the original article Hit count: 234

Filed under:
|
|

This really seems like a bug to me, but perhaps some databinding gurus can enlighten me? (My WinForms databinding knowledge is quite limited.)

I have a ComboBox bound to a sorted DataView. When the properties of the items in the DataView change such that items are resorted, the SelectedItem in my ComboBox does not keep in-sync. It seems to point to someplace completely random. Is this a bug, or am I missing something in my databinding?

Here is a sample application that reproduces the problem. All you need is a Button and a ComboBox:

public partial class Form1 : Form
{
    private DataTable myData;

    public Form1()
    {
        this.InitializeComponent();

        this.myData = new DataTable();
        this.myData.Columns.Add("ID", typeof(int));
        this.myData.Columns.Add("Name", typeof(string));
        this.myData.Columns.Add("LastModified", typeof(DateTime));
        this.myData.Rows.Add(1, "first", DateTime.Now.AddMinutes(-2));
        this.myData.Rows.Add(2, "second", DateTime.Now.AddMinutes(-1));
        this.myData.Rows.Add(3, "third", DateTime.Now);

        this.myData.DefaultView.Sort = "LastModified DESC";
        this.comboBox1.DataSource = this.myData.DefaultView;
        this.comboBox1.ValueMember = "ID"; 
        this.comboBox1.DisplayMember = "Name";
    }

    private void saveStuffButton_Click(object sender, EventArgs e)
    {
        DataRowView preUpdateSelectedItem = (DataRowView)this.comboBox1.SelectedItem;
        // OUTPUT: SelectedIndex = 0; SelectedItem.Name = third
        Debug.WriteLine(string.Format("SelectedIndex = {0:N0}; SelectedItem.Name = {1}", this.comboBox1.SelectedIndex, preUpdateSelectedItem["Name"]));

        this.myData.Rows[0]["LastModified"] = DateTime.Now;

        DataRowView postUpdateSelectedItem = (DataRowView)this.comboBox1.SelectedItem;
        // OUTPUT: SelectedIndex = 2; SelectedItem.Name = second
        Debug.WriteLine(string.Format("SelectedIndex = {0:N0}; SelectedItem.Name = {1}", this.comboBox1.SelectedIndex, postUpdateSelectedItem["Name"]));

        // FAIL!
        Debug.Assert(object.ReferenceEquals(preUpdateSelectedItem, postUpdateSelectedItem));
    }
}

© Stack Overflow or respective owner

Related posts about winforms

Related posts about databinding