none
How do I use DataGridViewComboBoxColumn with my own classes? RRS feed

  • Question

  • Ok, I have a DataGridView which is DataBound to a list of objects of class type "MainClass".

     

    MainClass has a property called "Target" which is of type "TargetClass" which goes like this:

    private TargetClass target;

    public TargetClass Target { get { return target; } set { target = value; }}

     

    Next I add a DataGridViewComboBoxColumn to my DataGridView as follows:

     

    DataGridViewComboBoxColumn  c = new DataGridViewComboBoxColumn ();

    c.DataSource = data;

     

    data is a special BindingList of class TargetClass. example:

    BindingList<TargetClass> data = new BindnigList<TargetClass>();

    // loop to add "TargetClass" members to data

     

    Now, when I load my DataGridView, the column initializes perfectly. It shows the dropdown, and the initial drop down value is set to whatever the value of "Target" is for each member of the DataGridView's datasource. And when I edit a cell the drop down properly shows the string representation of each TargetClass in the Combo Box's datasource. However when I attempt to set a new value I get an error:

     

    DataError: Invalid cast from 'System.String' to 'Test.TargetClass'.:  at System.Windows.Forms.Formatter.ChangeType(Object value, Type type, IFormatProvider formatInfo)
      at System.Windows.Forms.Formatter.ParseObjectInternal(Object value, Type targetType, Type sourceType, TypeConverter targetConverter, TypeConverter sourceConverter, IFormatProvider formatInfo, Object formattedNullValue)
      at System.Windows.Forms.Formatter.ParseObject(Object value, Type targetType, Type sourceType, TypeConverter targetConverter, TypeConverter sourceConverter, IFormatProvider formatInfo, Object formattedNullValue, Object dataSourceNullValue)
      at System.Windows.Forms.DataGridViewCell.ParseFormattedValueInternal(Type valueType, Object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
      at System.Windows.Forms.DataGridViewComboBoxCell.ParseFormattedValue(Object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
      at System.Windows.Forms.DataGridView.PushFormattedValue(DataGridViewCell& dataGridViewCurrentCell, Object formattedValue, Exception& exception) - test_value_a
    

    "test_value_a" corresponds to the "ToString" value of a particular TargetClass member.

    The question is why is it trying to set the value of the property with a string, and not the member itself?

    Any elegant solution to this?

    Wednesday, November 24, 2010 5:36 AM

Answers

  • It would appear from the information you supply that your class item is not typed. If it is typed then you have created a non-generic type that the system does not know about and therefore cannot handle the conversion for you.

      public class vehicleRecord
      {
        public long ID { get; set; }
        public string VEHICLE { get; set; }
        public string DETAILS { get; set; }
        public string DriverID { get; set; }
        public string DriverName { get; set; }
        public vehicleRecord(long _id, string _vehicleID, string _vehicleDetails, string _DriverID, string _DriverName)
        {
          ID = _id;
          VEHICLE = _vehicleID;
          DETAILS = _vehicleDetails;
          DriverName = _DriverName;
          DriverID = _DriverID;
        }
    
      }
    
    

    whenever a member of this class is referenced it returns a type which can be handled by the system.

    If you don't do this then you must force the type conversion using a cast thisvehicle.VEHICLE = (string)myelement;

    Hope this helps

    Regards

    Rupert

     


    the problem is not what you don't know it's what you think you know that's wrong
    Thursday, November 25, 2010 2:10 PM
  • Hi Trant,

     

    Welcome to MSDN Forums!

     

    The value displayed in cells in DataGridView are strings. Although you sign another type instance to it, it will auto call the ToString method to convert it to be a string and then display it in cells in DataGridView. Also, when you type things in cells also a string not the other type value. So the IDE would give you that message let you know you are sign a string value to a Test.TargetClass site.

     

    I think the better design for this situation is put a property into the BindingList not a TargetClass instance.

     

    If there's anything unclear or anything is not right in my post, please feel free to let me know.

     

    Have a nice weekend!

    Mike

    -------------------------------------------------------------------

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to the other community members reading the thread.

    *****************************************************

    [All-In-One Code Framework]

    Sample world! You will get more from this world!

    Welcome to the new world!

    Sunday, November 28, 2010 3:04 PM
    Moderator

All replies

  • It would appear from the information you supply that your class item is not typed. If it is typed then you have created a non-generic type that the system does not know about and therefore cannot handle the conversion for you.

      public class vehicleRecord
      {
        public long ID { get; set; }
        public string VEHICLE { get; set; }
        public string DETAILS { get; set; }
        public string DriverID { get; set; }
        public string DriverName { get; set; }
        public vehicleRecord(long _id, string _vehicleID, string _vehicleDetails, string _DriverID, string _DriverName)
        {
          ID = _id;
          VEHICLE = _vehicleID;
          DETAILS = _vehicleDetails;
          DriverName = _DriverName;
          DriverID = _DriverID;
        }
    
      }
    
    

    whenever a member of this class is referenced it returns a type which can be handled by the system.

    If you don't do this then you must force the type conversion using a cast thisvehicle.VEHICLE = (string)myelement;

    Hope this helps

    Regards

    Rupert

     


    the problem is not what you don't know it's what you think you know that's wrong
    Thursday, November 25, 2010 2:10 PM
  • Hi Trant,

     

    Welcome to MSDN Forums!

     

    The value displayed in cells in DataGridView are strings. Although you sign another type instance to it, it will auto call the ToString method to convert it to be a string and then display it in cells in DataGridView. Also, when you type things in cells also a string not the other type value. So the IDE would give you that message let you know you are sign a string value to a Test.TargetClass site.

     

    I think the better design for this situation is put a property into the BindingList not a TargetClass instance.

     

    If there's anything unclear or anything is not right in my post, please feel free to let me know.

     

    Have a nice weekend!

    Mike

    -------------------------------------------------------------------

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to the other community members reading the thread.

    *****************************************************

    [All-In-One Code Framework]

    Sample world! You will get more from this world!

    Welcome to the new world!

    Sunday, November 28, 2010 3:04 PM
    Moderator