views:

57

answers:

1

I have a DataGridView which DataSource is connected to objects. Everything works OK (I can edit that objects and the change is persisted) until I want to choose using the combobox connected object (in the database it is connected via foreign key).

I can fill the combobox so that the proper values are shown (ie. user's name). I do this by selecting the datasource for that particular column. It allows me to choose the displayed properties as well as the value (but I cannot set the value to the WHOLE chosen object). However, when the object is being saved, the error occurs. DataGridView is trying to save the value of the selected object (property of this "foreign object"), but not the object itself.

How can I convince DataGridView to save the selected object and not only the one of its property?

+1  A: 

This is one of common problems. You cannot do this with original DataGridViewComboboxColumn. I found a solution some time ago - you have to subclass it. Here's the code:

   public class DataGridViewBusinessComboBoxColumn : DataGridViewComboBoxColumn
    {
        public DataGridViewBusinessComboBoxColumn()
        {
            CellTemplate = new DataGridViewBusinessComboBoxCell();
        }
    }

    public class DataGridViewBusinessComboBoxCell : DataGridViewComboBoxCell
    {
        private System.ComponentModel.PropertyDescriptor displayProp;

        private CurrencyManager ListManager
        {
            get
            {
                BindingMemberInfo bmi = new BindingMemberInfo(base.DisplayMember);
                if (DataGridView != null)
                {
                    return (CurrencyManager)
                           DataGridView.BindingContext[DataSource, bmi.BindingPath];
                }
                return null;
            }
        }

        private System.ComponentModel.PropertyDescriptor DisplayProp
        {
            get
            {
                if (displayProp == null)
                {
                    displayProp = ListManager.GetItemProperties().Find(DisplayMember,
                                                                       true);
                }
                return displayProp;
            }
        }

        protected override object GetFormattedValue(object value, int rowIndex,
                                                    ref DataGridViewCellStyle cellStyle,
                                                    TypeConverter valueTypeConverter,
                                                    TypeConverter formattedValueTypeConverter,
                                                    DataGridViewDataErrorContexts
                                                        context)
        {
            if (value == null || value == cellStyle.DataSourceNullValue)
                return "";

            return base.GetFormattedValue(DisplayProp.GetValue(value),
                                          rowIndex, ref cellStyle, valueTypeConverter,
                                          formattedValueTypeConverter, context);
        }

        public override object ParseFormattedValue(object formattedValue,
                                                   DataGridViewCellStyle cellStyle,
                                                   TypeConverter formattedValueTypeConverter,
                                                   TypeConverter valueTypeConverter)
        {
            foreach (object item in ListManager.List)
            {
                if ((string) DisplayProp.GetValue(item) == (string) formattedValue)
                    return item;
            }

            return base.ParseFormattedValue(formattedValue, cellStyle,
                                            formattedValueTypeConverter, valueTypeConverter);
        }
}
kubal5003