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

MVVM and heterogeneous model types

12 Answers 123 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Jan
Top achievements
Rank 1
Jan asked on 15 Jul 2013, 04:07 PM
Hi guys,

I've got to display data from different models in one gridview. The models have some common properties, but some models also have exclusiv properties.

My approach is to create a specific viewmodel type (derived from a common base viewmodel type) for every model type, that I need to display in the gridview. In the viewmodels I simply create a readonly property returning "NA" for those properties, that are not available at the corresponding model type.

So far so good, but there're two problems I can't solve:

  • Filtering and Sorting is gone (I'm a newbee and was hoping to be able to use the auto-creation of these features, which worked without my viewmodels.)
  • When trying to modify a dummy property (which has no setter and is supposed to be readonly) an exception occurs. (A TwoWay or OneWayToSource binding cannot work on the read-only property)

Here're examples of two viewmodels:

public class BaseItemViewModel : ViewModelBase
{
    private BaseItem _baseItem;
 
    public BaseItemViewModel(BaseItem baseItem)
    {
        _baseItem = baseItem;
    }
 
    public string ItemId
    {
        get
        {
            return _baseItem.ItemId;
        }
    }
 
    public string CollectionId
    {
        get
        {
            return _baseItem.CollectionId;
        }
    }
 
    public DateTime CreationDate
    {
        get
        {
            return _baseItem.CreationDate;
        }
    }
 
    public string Name
    {
        get
        {
            return "NA";
        }
    }
 
    public string Description
    {
        get
        {
            return "NA";
        }
    }
 
    public string CreatorCollectionId
    {
        get
        {
            return "NA";
        }
    }
}
 
 
public class ItemViewModel : ViewModelBase
{
    private Item _item;
 
    public ItemViewModel(Item item)
    {
        _item = item;
    }
 
    public string ItemId
    {
        get
        {
            return _item.ItemId;
        }
    }
 
    public string CollectionId
    {
        get
        {
            return _item.CollectionId;
        }
    }
 
    public DateTime CreationDate
    {
        get
        {
            return _item.CreationDate;
        }
    }
 
    public string Name
    {
        get
        {
            return _item.Name;
        }
        set
        {
            _item.Name = value;
        }
    }
 
    public string Description
    {
        get
        {
            return _item.Description;
        }
        set
        {
            _item.Description = value;
        }
    }
 
    public string CreatorCollectionId
    {
        get
        {
            return _item.CreatorCollectionId;
        }
        set
        {
            _item.CreatorCollectionId = value;
        }
    }
}


Any help is highly appreciated.

Cheers,

Jan

12 Answers, 1 is accepted

Sort by
0
Dimitrina
Telerik team
answered on 18 Jul 2013, 01:38 PM
Hello,

Would you please set the ItemType for the RadGridView.Items to be the base class? What is the result if your data is homogeneous, do you experience the same problem with filtering and sorting?
 
Let me know if this solves the issue.

Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Jan
Top achievements
Rank 1
answered on 18 Jul 2013, 08:59 PM
Hi Didie,

thanks for the reply!

When using homogeneous data (commenting out the lines where I add the baseItem), the control works as expected. I'm not sure what you mean with "setting the item type to the base class"? (Maybe I've done it already ...) Here's the code for the viewmodel:

public class ItemsExplorerViewModel : INotifyPropertyChangedBase
{
    public ObservableCollection<ViewModelBase> GetItems()
    {
        ObservableCollection<ViewModelBase> _items = new ObservableCollection<ViewModelBase>();
        for (int i = 0; i < 5; i++)
        {
            Item item = new Item();
            item.Name = "Jan " + i;
            item.Description = "Das ist ein Test";
            ItemViewModel itemViewModel = new ItemViewModel(item);
            _items.Add(itemViewModel);
 
            BaseItem baseItem = new BaseItem();
            BaseItemViewModel baseItemViewModel = new BaseItemViewModel(baseItem);
            _items.Add(baseItemViewModel);
        }
        return _items;
    }
}

Cheers,

Jan
0
Dimitrina
Telerik team
answered on 19 Jul 2013, 09:22 AM
Hello,

What I meant is to set the ItemType similar to:

gridView.Items.ItemType = typeof(ViewModelBase);
 

Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Jan
Top achievements
Rank 1
answered on 19 Jul 2013, 12:51 PM
Hi Didie,

thanks for the explanation. Now, I've just tried it. Unfortunately with no success.

Cheers,

Jan
0
Dimitrina
Telerik team
answered on 19 Jul 2013, 01:15 PM
Hello,

We are executing lambda expressions at run-time for all kinds of purposes -- filtering, sorting, grouping and so on. Actually we use LINQ to perform almost everything in RadGridView. What is the type of the properties of the base type you would like to allow filtering and sorting on?
 

Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Jan
Top achievements
Rank 1
answered on 19 Jul 2013, 01:27 PM
Hi,

String and DateTime. All pretty simple. Below are the models for my test implementation ...

Basically I need to display instances of both models in a GridView and be able to use the build-in sorting and filtering. The only way I could think of was to create a viewmodel for each base model with dummy-properties where applicable. However, I'm open to any solution.

public class BaseItem : INotifyPropertyChangedBase
{
    private readonly string _itemId;
    private readonly string _collectionId;
    private readonly DateTime _creationDate;
 
    public BaseItem()
    {
        _itemId = Guid.NewGuid().ToString();
        _collectionId = Guid.NewGuid().ToString();
        _creationDate = DateTime.Now;
    }
 
    public BaseItem(String itemId, String collectionId, DateTime creationDate)
    {
        _itemId = itemId;
        _collectionId = collectionId;
        _creationDate = creationDate;
    }
 
    public string ItemId
    {
        get
        {
            return _itemId;
        }
 
    }
 
    public string CollectionId
    {
        get
        {
            return _collectionId;
        }
    }
 
    public DateTime CreationDate
    {
        get
        {
            return _creationDate;
        }
    }
}
 
public class Item : BaseItem
{
    private String _name = "";
    private String _description = "";
    private String _creatorCollectionId;
 
 
    public Item()
        : base()
    {
        _creatorCollectionId = "Jan"; //later, get userCollectionId from Session
    }
 
    public Item(String itemId, String collectionId, DateTime creationDate, String name, String description, String creatorCollectionId)
        : base(itemId, collectionId, creationDate)
    {
        _name = name;
        _description = description;
        _creatorCollectionId = creatorCollectionId;
    }
 
    public string Name
    {
        get
        {
            return _name;
        }
 
        set
        {
            SetProperty(ref _name, value);
        }
    }
 
    public string Description
    {
        get
        {
            return _description;
        }
 
        set
        {
            SetProperty(ref _description, value);
        }
    }
 
    public string CreatorCollectionId
    {
        get
        {
            return _creatorCollectionId;
        }
 
        set
        {
            SetProperty(ref _creatorCollectionId, value);
        }
    }
}

Cheers,

Jan
0
Jan
Top achievements
Rank 1
answered on 19 Jul 2013, 01:31 PM
In case you were refering to the ViewModelBase class ... it has no properties, just an empty class:

public abstract class ViewModelBase : INotifyPropertyChangedBase
{
}

Cheers,

Jan
0
Dimitrina
Telerik team
answered on 23 Jul 2013, 03:31 PM
Hello,

Thank you for sharing your code. I have created a test project in my attempt to reproduce an issue with the filtering and sorting. I were not able to.

Would you please check the attached sample and let me know how is your solution different from mine? 

Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Jan
Top achievements
Rank 1
answered on 24 Jul 2013, 05:22 AM
Hi Didie,

your example works, but it doesn't have the "feature" that all available properties are shown as columns. Further, for items, which don't have a certain property, a placeholder text should be shown (e.g. "NA").

You would need to build an example using the ViewModels, which I have posted earlier (see also an earlier post for the code of the class "ItemExplorerViewModel", which creates the items).

My observations so far:

  • With AutoGenerateColumns="True" in the GridView set and creating heterogeneous ViewModels of both types (Method "GetItems" of the class "ItemsExplorerViewModel"), nothing is shown.
  • With AutoGenerateColumns="True" in the GridView set and creating homogeneous ViewModels of just one type, the Grid is shown as expected with filtering und sorting.
  • With AutoGenerateColumns="False" in the GridView set, setting the columns manually and creating heterogeneous ViewModels of both types, all columns and properties are shown, but filtering and sorting is not enabled.
  • With AutoGenerateColumns="False" in the GridView set, setting the columns manually and creating homogeneous ViewModels of just one type, the Grid is shown as expected with filtering und sorting.

Any idea? Many thanks,

Jan

0
Dimitrina
Telerik team
answered on 24 Jul 2013, 04:48 PM
Hello Jan,

Would it be possible for you to update my project so that to illustrate the different scenarios you have described?
 

Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Jan
Top achievements
Rank 1
answered on 25 Jul 2013, 03:49 AM
Hi Didie,

a demo project is ready to be uploaded, but I'm not allowed to upload *.zip files (only gif, jpg, png, jpeg)

How should I transfer the project to you?

Cheers,

Jan
0
Yordanka
Telerik team
answered on 25 Jul 2013, 05:51 AM
Hello Jan,

Please open a support ticket and upload your project there.
 
Regards,
Yordanka
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Tags
GridView
Asked by
Jan
Top achievements
Rank 1
Answers by
Dimitrina
Telerik team
Jan
Top achievements
Rank 1
Yordanka
Telerik team
Share this question
or