We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Data binding Custom Object IList with descendant objects in the list

I am trying to data bind a IList of objects to the grid's drowdownlist. This list contains objects that descend from one another. For example, it might contain objects of Class1 and Class2, where Class2 inherits directly from Class1.

The drop down list appears correctly in the grid for all the objects in the list. However, if i select an item in the list that is of type Class2, I get an InvalidCastException - Object must implement IConvertible.

This is happening when the value is being set on the underlying record - there is a call to NullableHelper.ChangeType which calls Convert.ChangeType:

Syncfusion.ComponentModel.NullableHelper:
public static object ChangeType(object value, Type type)
{
return Convert.ChangeType(value, type);
}

The type that is passed in is from the Column's field descriptor which is of type Class1.

Isn't this call really only necessary if the passed in value is a ValueType? ie, int, decimal, float, etc.?

Can the grid's dropdown list be modified to support selection of descendant objects?

Regards,
Minh Tran

6 Replies

AD Administrator Syncfusion Team January 9, 2007 06:57 AM UTC

Hi Minh,

Please try the attached sample and let me know if you are trying something different.
GDBGDropDownCollections.zip

Best Regards,
Haneef


MT Minh Tran January 9, 2007 05:45 PM UTC

Hi Haneef,

No that is not what I'm trying to do. I've attached a demo Visual Studio 2003 project.

Essentially, I am binding custom objects - not datasets / datatables to the GridGroupingControl. One of the columns I've mapped - the Customer column draws from a datasource that has both Customer & GoodCustomer(GoodCustomer descends from Customer) objects in the IList. When you click on the Customer column drop down list in the grid you'll see 4 potential customers. The first 2 are Customer objects. The second 2 are GoodCustomer objects. If you pick the first 2, the grid has no problem setting the underlying record's value with your pick. If you pick one of the second 2, and then navigate off the column, you'll see a red exclamation mark next to the column showing an Inconvertible exception.

Syncfusion Version 4.111.0.50

Thanks,
Minh Tran


CustomObjectDataBinding.zip


AD Administrator Syncfusion Team January 10, 2007 10:10 AM UTC

Hi Minh,

Thanks for your sample.

You should implement the ICovertible interface for coverting the GoodCustomer to Customer. Please refer to the attached sample for implementation and let me know if this helps.

Sample : ModifiedCustomObjectDataBinding.zip

Best Regards,
Haneef

public class Customer:IConvertible
{
public Customer(){}

public Customer(int id, string first, string last) {
this.id = id;
this.first = first;
this.last = last;
}
private int id;
public int ID
{
get {return id;}
set {id = value;}
}
private string first;
public string First
{
get {return first;}
set {first = value;}
}
private string last;
public string Last
{
get {return last;}
set {last = value;}
}
public string FullName
{
get {return first + " " + last;}
}
#region RequiredIConvertible Members

public string ToString(IFormatProvider provider)
{return this.FullName; }

public object ToType(Type conversionType, IFormatProvider provider)
{
if( conversionType == typeof(GoodCustomer))
return new GoodCustomer(this.ID,this.First,this.Last);
return null;
}
#endregion

#region DefaultIConvertible Members
///Default ICovertible member source code here.
#endregion

}


MT Minh Tran January 10, 2007 04:10 PM UTC

Hi Haneef,

The sample I gave you is something i just wrote up quickly to demonstrate the issue.

I do not have control of the object hierarchy in the business domain - they come from a different team of developers I work with.

My question is why is it necessary for Syncfusion to call Convert.ChangeType when setting the underlying record's value for a reference type? It doesn't make sense that I have to convert an object that descends from another object to a type that is it's parent.

If a cell's value is bound to an object that is of Type1. And another object is selected that is Type2(which descends from Type1), why shouldn't this be allowed without converting Type2 to Type1?

That's the whole point of OOP inheritance.

Regards,
Minh Tran


TG Tod Golding May 30, 2007 08:48 PM UTC

This appears to be similar to a problem I'm having. I cannot appear to bind columns to custom data objects without requiring those objects to implement IConvertible. I'd been trying this with my own custom cell type and assumed it was just something I was doing wrong. Now I'm just trying to use a vanilla autocomplete combobox cell and I'm running into the same problem. My combo is populated with objects of "MyCustomType" and the column is bound to a columns with type of "MyCustomType" and I'm getting the "must implement IConvertible" error.

Can some please clarify what *is* and *is not* required when binding columns to custom data objects? I cannot use this control if it is going to impose requirements on my business objects. Please tell me there's something I'm overlooking.




>Hi Haneef,

The sample I gave you is something i just wrote up quickly to demonstrate the issue.

I do not have control of the object hierarchy in the business domain - they come from a different team of developers I work with.

My question is why is it necessary for Syncfusion to call Convert.ChangeType when setting the underlying record's value for a reference type? It doesn't make sense that I have to convert an object that descends from another object to a type that is it's parent.

If a cell's value is bound to an object that is of Type1. And another object is selected that is Type2(which descends from Type1), why shouldn't this be allowed without converting Type2 to Type1?

That's the whole point of OOP inheritance.

Regards,
Minh Tran


HA haneefm Syncfusion Team May 30, 2007 11:10 PM UTC

Hi Tod,

One way you can avoid this problem by deriving the GridComboBoxCellRenderer class and override the OnSaveChanges method. Here is a code snippet to show this.

public class MyComboBoxCellModel : GridComboBoxCellModel
{
public MyComboBoxCellModel(GridModel grid): base(grid)
{ }

public override GridCellRendererBase CreateRenderer(GridControlBase control)
{
return new MyComboBoxCellRenderer(control, this);
}
}

public class MyComboBoxCellRenderer : GridComboBoxCellRenderer
{
public MyComboBoxCellRenderer(GridControlBase grid, GridCellModelBase cellModel) : base(grid, cellModel)
{ this.SupportsFocusControl = false; }

protected override bool OnSaveChanges()
{
Type type = this.Grid.Model[this.RowIndex,this.ColIndex].CellValue.GetType();

if (type == this.ControlValue.GetType())
return base.OnSaveChanges();
else
{
Customer cust = new Customer();
cust.ID = (this.ControlValue as GoodCustomer).ID;
cust.First = (this.ControlValue as GoodCustomer).First;
cust.Last = (this.ControlValue as GoodCustomer).Last;
this.Grid.Model[this.RowIndex, this.ColIndex].CellValue = cust;
}
return true;
}
}

Here is a modified sample.
http://websamples.syncfusion.com/samples/Grid.Windows/F61685/main.htm

Best regards,
Haneef

Loader.
Live Chat Icon For mobile
Up arrow icon