Bill February 2016

Associate two classes so a combobox appears with the second class

I have a Winforms application. There are two classes. One class stores the people that contribute to a book. The other class is a list of possible contribution types (like editor, reviewer, and so on).

The BookContributors class is the datasource for my datagridview and that works just fine. Now, I want to have the BookContributorTypes class be a combobox that feeds the BookContributors class.

So far in my reading, it looks like I have a number of options, including forcing a combobox into the datagridview, using class attributes, creating a 1-to-many relationship between classes.

Since my code will have many of these types of situations, I want to do this right. I think this means showing the relationship between the two classes somehow so the datagridview knows to just display the combobox, but I am not sure how to go about doing this.

BookContributors is populated by a person filling out a contributor. Example: BookContributor = "John Smith"; BookContributorFileAs="Smith, John"; BookContributorType = "rev".

public class BookContributors : INotifyPropertyChanged
{
    private string _bookContributor;
    [DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorComment")]
    [DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorDisplayName")]
    public string BookContributor
    {
        get { return _bookContributor; }
        set
        {
            if (SetField(ref _bookContributor, value, "BookContributor"))
            {
                // When the user types an author name, add the sorted name to the sorted field.
                //  ex Name = William E Raymond
                //  ex File As = Raymond, William E
                var name = _bookContributor.Split(' ');
                if (name.Length >= 2)
                {
                    string fileAsName = (name[name.Length - 1] + ",");
                    for (int i = 0; i <= (name.Length - 2)        

Answers


VV5198722 February 2016

I'm working with WinForms DataGridView for several years. AFAIK the DataGridView is not as smart as you expect. You have to setup comboBox columns manually, i.e. on event DataBindingComplete

  • create new DataGridViewComboBoxColumn
  • set its DataPropertyName property to "BookContributorType"
  • add it to DataGridViewColumnCollection
  • set its DataSource property to a collection of BookContributorTypes
  • set its ValueMember property to "BookContributorTypeId"
  • set its DisplayMember property to "BookContributorTypeDescription"
  • adopt properties from auto-generated column corresponding BookContributorTypes like DisplayIndex
  • remove auto-generated column

I'm using wrapper classes around DataGridView to get a smarter control. In this way I've reduced source code everywhere I'm using DataGridView.

Here is a code snippet to replace an auto-generated column with a comboBox column:

DataGridViewColumn auto // = ... auto-generated column to be replaced
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
combo.DataPropertyName = auto.DataPropertyName;
combo.Name = auto.Name;
DataGridView dgv = auto.DataGridView;
dgv.Columns.Add(combo);

combo.DataSource = GetBookContributorTypes; // collection of comboBox entries
combo.ValueMember = "BookContributorTypeId";
combo.DisplayMember = "BookContributorTypeDescription";

// adopt further properties if required
combo.Frozen = auto.Frozen;
combo.DisplayIndex = auto.DisplayIndex;
combo.Visible = auto.Visible;
combo.ReadOnly = auto.ReadOnly;
combo.HeaderText = auto.HeaderText;
combo.HeaderCell.ToolTipText = auto.HeaderCell.ToolTipText;
combo.SortMode = auto.SortMode;
combo.Width = auto.Width;

dgv.Colum 


Bill February 2016

This ended up being a lot more difficult to research than I originally thought. It turns out, if you want to place a column in a DataGridView with a combobox and have that combobox interact with another class, it is not a quick one-liner.

My example has two classes:

  • BookContributors (bookContributors) - A list of people that have contributed to a book. For example, this stores a person's name and the type of contribution they made.
  • BookContributorTypes (bookContributorTypes) - A list of possible types of contributions to a book, like Editor or Contributor.
  • I want the ContributorTypes class to be a combobox and store the user's selection into the BookContributors class, specifically the BookContributorType property.

Here is the code I came up with, along with some additional notes I found along the way. To the best of my knowledge, the information I provide is accurate :-)

    gvContributors.DataSource = bookContributors; //set the datgridview's datasource so it displays the class you want.
    gvContributors.Columns["BookContributorType"].Visible = false; //hide the column (property) you want to replace with a combobox.

    DataGridViewComboBoxColumn contribType = new DataGridViewComboBoxColumn(); //create a combobox object.
    contribType.HeaderText = "My Column"; //the text to display in the column header.
    contribType.Name = "BookContributorType"; //name of the class property you set to Visible=false. Note sure if this is needed.
    contribType.DataSource = bookContributorTypes; //name of the class that provides the combobox data.
    contribType.DisplayMember = "BookContributorTypeDescription"; //data the user will see when clicking the combobox.
    contribType.ValueMember = "BookContributorTypeId"; //data to store in the class property.
    contribType.DataPropertyName = "Bo 

Post Status

Asked in February 2016
Viewed 1,952 times
Voted 11
Answered 2 times

Search




Leave an answer