Search code examples
c#datagridviewcomboboxbindingsourcelookup-tables

ComboBox.SelectedValue not working as expected


So I have a DataGridView which I am using as a “row selector” on a form, and a bunch of controls are bound to the bindingSource.

One of the bound controls is a ComboBox serving as a lookup which enables status choices for the rows, this is populated from a DataTable with data pulled from the DB.

The population of this box is without any issue.

When a given row is selected from the DGV the form controls display data from the given row as they should, however the “statusComboBox” is not quite playing the game.

If in the DGV, I choose a row that has a different status to one previously selected, it works as it should, however, if I choose a row with the same value to a previously selected row, instead of the box showing the DisplayMember it shows the ValueMember.

IT only seems to occur in the above scenario, where the rows selection only instigates a display response from the bound ComboBox providng a previous selection had a different “Status ID”. What have I dont wrong that would cause this behaviour?

So the form load looks like this

private void ProjectsForm_Load(object sender, EventArgs e)
{  
    InitBindingSource();

    //// bind Selector
    //ASMod$ this needs to be 'true' unless you explicitly declare columns
    ProjectsDataGridView.AutoGenerateColumns = false;
    ProjectsDataGridView.DataSource = ProjectsBindingSource;

    GetData();

    //Set GeneralStatusBox
    Helpers.GeneralStatusInitLookup(statusComboBox, ProjectsBindingSource);
}

The ProjectBindingSource is initialised thus:

private void InitBindingSource()
{
    ProjectsBindingSource = new BindingSource();
    projectsBindingNavigator.BindingSource = ProjectsBindingSource;
    ProjectsBindingSource.PositionChanged += new EventHandler(ProjectsBindingSource_PositionChanged);
}

A ProjectsAddDataBindings procedure, and the contained DataBindings.Add for the ComboBox (executed at the end of a GetData routine that additionally populated ProjectsBindingSource):

ProjectsAddDataBindings();
{
    …
    this.statusComboBox.DataBindings.Add("Text", ProjectsBindingSource, "GSID");
    …
}

After the GetData block the GeneralStatusInitLookup populates the Lookup elements, in a helper class simply because it provides functionality to a number of different forms

public static void GeneralStatusInitLookup(System.Windows.Forms.ComboBox comboBox, BindingSource primaryBindingSource)
{
    string statusFilter = "";
    statusFilter = Helpers.GetStatusGroupFilter(EndeavourForm.FilterId);
    if (statusFilter != "")
    {
        statusFilter = " WHERE " + statusFilter;
    }
    //// string statusFilter = ""; //// temp

    string sql = "";
    sql = "SELECT GSID, ShortName FROM GeneralStatus" + statusFilter + " ORDER BY Pos";
    GeneralStatusDataTable = Helpers.Db.GetDataTable(sql);

    comboBox.DataSource = GeneralStatusDataTable;
    comboBox.DisplayMember = "ShortName";
    comboBox.ValueMember = "GSID";

    comboBox.DataBindings.Add(new Binding("SelectedValue", primaryBindingSource.DataSource, "GSID"));
}

And the DGV initiated row change is handled like this

private void ProjectsBindingSource_PositionChanged(object sender, EventArgs e)
{
    try
    {
        // Update the database with the user's changes.
        UpdateProjects();
        statusComboBox.SelectedValue = (int)CurrentDataRowView.Row["GSID"];
    }
    catch (Exception)
    {
    }
}

private void UpdateProjects()
{
    try
    {
        ProjectsDataAdapter.Update((DataTable)ProjectsBindingSource.DataSource);

        DataHelper.CommitProposedChanges(projectsDataSet);
        if (this.projectsDataSet.HasChanges() == true)
        {
            ProjectsBindingSource.EndEdit();
            ProjectsDataAdapter.Update();
        }

        CurrentDataRowView = (DataRowView)ProjectsBindingSource.Current;
    }
    catch (InvalidOperationException)
    {
        throw;
    }
    catch (Exception)
    {
        throw;
    }
}

Anyway I hope I haven't swamped readers with to much code, but frankly I cant see where this is going wrong. So any help would be greatly appreciated.


Solution

  • This was a simple solution in the end. Both the GeneralStatusInitLookup() and the ProjectsAddDataBindings() blocks made use of DataBindings.Add ... For the lookup table this was fine, but with the binding to the main table; the later, I had used "Text" as the propertyName parameter.