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); i++)
                    {
                        fileAsName = fileAsName + " " + name[i];
                    }
                    BookContributorFileAs = fileAsName;
                }
            }
        }
    }
    private string _bookContributorFileAs;
    [DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorFileAsComment")]
    [DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorFileAsDisplayName")]
    public string BookContributorFileAs { get { return _bookContributorFileAs; } set { SetField(ref _bookContributorFileAs, value, "BookContributorFileAs"); } }
    private string _bookContributorType;
    [DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorTypeComment")]
    [DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorTypeDisplayName")]
    public string BookContributorType { get { return _bookContributorType; } set { SetField(ref _bookContributorType, value, "BookContributorType"); } }
    #region handle property changes
    public event PropertyChangedEventHandler PropertyChanged;
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        //if the value did not change, do nothing.
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        //the value did change, so make the modification.
        field = value;
        return true;
    }
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}
BookContributorTypes (populated with a list of bookContributor types from an XML file). Example Book contributor type ID's: "rev", "edt". Example Book contributor type descriptions: "Reviewer", "Editor".
class BookContributorTypes : INotifyPropertyChanged
{
    private string _bookContributorTypeId;
    [DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorTypeIdComment_lkp")]
    [DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorTypeIdDisplayName_lkp")]
    public string BookContributorTypeId { get { return _bookContributorTypeId; } set { SetField(ref _bookContributorTypeId, value, "BookContributorTypeId"); } }
    private string _bookContributorTypeDescription;
    [DescriptionLocalized(typeof(ResourcesClassBooks), "BookContributorTypeComment_lkp")]
    [DisplayNameLocalized(typeof(ResourcesClassBooks), "BookContributorTypeDisplayName_lkp")]
    public string BookContributorTypeDescription { get { return _bookContributorTypeDescription; } set { SetField(ref _bookContributorTypeDescription, value, "BookContributorTypeDescription"); } }
    #region handle property changes
    public event PropertyChangedEventHandler PropertyChanged;
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        //if the value did not change, do nothing.
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        //the value did change, so make the modification.
        field = value;
        return true;
    }
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}
All I have working right now, without the combo box, because I do not know how to implement a combobox to show the selection options from the BookContributorTypes class:
dataGridView1.DataSource = bookContributors;
Thanks for ay help you can provide.