This is a migrated thread and some comments may be shown as answers.

Problems changing DataSource and using an interface type

2 Answers 96 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Jérôme
Top achievements
Rank 1
Jérôme asked on 11 Apr 2014, 03:38 PM
Hi.

I'm having problems with RadListView, regarding the change of DataSource.

First problem : using an Interface type
Here is what I do : I am using RadListView, in details mode, to list objects, implementing a common interface, let's say IListItem.  As a DataSource, I am using a IListItem[ ].

Let's say I have an array containing two or more types implementing the interface : TypeA and TypeB.
Using that array as the datasource will do nicely.

If I use an array containing only objects of TypeA, the RadListView will create not only columns based on IListItem, but also add columns based on TypeA. Is this a desired behavior? I would expect only to see columns based on IListItem.

I have been able to work around this with ColumnCreating event, adding :
switch (e.Column.FieldName)
{
...
 default:
                    e.Column.Visible = false;
}

Second problem :

Assuming the same conditions (interface type IListItem, two types implementing it TypeA and TypeB)

At first, the DataSource is defined with a large array, containing both TypeA and TypeB. After a search (the search is full text and made on sqlserver, a new array is then constructed with new objects), the datasource is changed this way :
radListView1.DataSource = array;

If it occurs that the new array contains only TypeA, I get a System.Reflection.TargetInvocationException. The stack trace shows the last call from Telerik code comes from : Telerik.WinControls.Data.RadListSource`1.GetBoundValue.

And it looks like the reflection exception is trying to access TypeB directly, instead of using the interface (my exception is in french, but it would probably be object does not match target type). It start in my ColumnCreating method, the event being fired after the datasource update.

That looks a bit to what is described in this thread :
http://www.telerik.com/forums/refresh-data-in-radlistview-problem#Hlgoam9vfkaKvqTGSWdttg

My understanding was that the bug was fixed, but I have been able to work around it this way :
radListView1.Columns.Clear();
radListView1.DataSource = null;

before updating the DataSource. Not clearing the Columns seems to affect the AutoSizeMode defined in ColumnCreating because the columns are all too small after a datasource change. Even with Columns.Clear, the AutoSizeMode is not perfect, but it is still better. One of my columns looks a bit too small, maybe adjusting only  at first time?

Thanks!

2 Answers, 1 is accepted

Sort by
0
Jérôme
Top achievements
Rank 1
answered on 11 Apr 2014, 09:00 PM
Hi. I think I found a better workaround for the second problem (or solution...)

The exception was raised in my ColumnCreating handler. The method is basically a switch on the column name that sets the BestFitMod. At the end, I was calling : e.Column.BestFit. That was where the exception was raised. Maybe it was not supposed to be there? Not even sure if BestFit() is related with AutoSizeMode....

Anyway, I put the BestFit call after the DataSource change instead of ColumnCreating and I have no more TargetInvocationException. I can even remove the call to DataSetNull and Columns.Clear.
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 16 Apr 2014, 11:17 AM
Hello Jérôme,

Thank you for contacting Telerik Support.

When you bind a RadListView (DetailsView) to a collection of custom objects, depending on the available properties of the custom objects, such columns are created. However, when you have a collection of a base class or interface and this collection contains elements of different derivative types, only columns for the common properties are created. In all other cases, when the collection is composed of identical objects, columns for the object's properties are created. This is desired behavior. Of course, as you already found out, it is possible to hide the undesired columns.

Here is a sample code snippet, demonstrating the appropriate approach for changing the data source and adjusting the columns width after the new data source is set:
public Form1()
{
    InitializeComponent();
 
    IListItem[] items = new IListItem[10];
 
    for (int i = 0; i < 5; i++)
    {
        items[i] = new ItemA(i,"Title" + i);
    }
    for (int i = 5; i < items.Length; i++)
    {
        items[i] = new ItemB(i,"Description" + i,i * 0.25m);
    }
 
    this.radListView1.DataSource = items;
    this.radListView1.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView;
    DetailListViewElement detailsView = this.radListView1.ListViewElement.ViewElement as DetailListViewElement;
    detailsView.BestFitColumns();
}
 
private void radButton1_Click(object sender, EventArgs e)
{
    IListItem[] items = new IListItem[5];
 
    for (int i = 0; i < 5; i++)
    {
        items[i] = new ItemA(i,"Title" + i);
    }
 
    this.radListView1.DataSource = items;
    DetailListViewElement detailsView = this.radListView1.ListViewElement.ViewElement as DetailListViewElement;
    detailsView.BestFitColumns();
}
 
public class ItemA:IListItem
{
    private int id;
 
    public string TitleA { get; set; }
 
    public ItemA(int idA, string titleA)
    {
        this.id = idA;
        this.TitleA = titleA;
    }
 
    public int Id
    {
        get
        {
            return this.id;
        }
        set
        {
            this.id = value;
        }
    }
}
 
public class ItemB:IListItem
{
    private int id;
 
    public string DescriptionB { get; set; }
 
    public decimal PriceB { get; set; }
 
    public ItemB(int idB, string titleB, decimal priceB)
    {
        this.id = idB;
        this.DescriptionB = titleB;
        this.PriceB = priceB;
    }
 
    public int Id
    {
        get
        {
            return this.id;
        }
        set
        {
            this.id = value;
        }
    }
}
 
public interface IListItem
{
    int Id { get; set; }
}

Should you have further questions, I would be glad to help.

Regards,
Desislava
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
ListView
Asked by
Jérôme
Top achievements
Rank 1
Answers by
Jérôme
Top achievements
Rank 1
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or