Philipp Seif
Philipp Seif

Reputation: 1

Collection of ObservableCollections of different types

I'm working on a problem where I have two nested TabControls. Both should bind to a collection. The parent tab control should bind to a collection called devices. This devices-collection should contain several ObservableCollections of different types which should be displayed in a different way in the ContentTemplate.

I tried something like this:

public ObservableCollection<CellPhone> CellPhones { get; set; }

public ObservableCollection<Watch> Watches { get; set; }

public ObservableCollection<ObservableCollection<DeviceItem>> Devices { get; set; }

Watch and CellPhone inherit from DeviceItem.

I tried the following:

CellPhones = new ObservableCollection<CellPhone>();
Watches = new ObservableCollection<Watch>();
Devices = new ObservableCollection<ObservableCollection<DeviceItem>>();
Devices.Add(CellPhones); // it fails here...

It says:

cannot convert from 'System.Collections.ObjectModel.ObservableCollection<CellPhone>' to 'System.Collections.ObjectModel.ObservableCollection<DeviceItem>'

I do understand this error message, but I haven't found a workaround.

I read about covariance in c#, but apparently that's not working for ObservableCollections.

Do you have another idea on how to solve this?

Upvotes: 0

Views: 1074

Answers (3)

Amir Hajiha
Amir Hajiha

Reputation: 935

What I am doing in Xamarin.Forms is using Interfaces.

So, imaging I have a class with name Student and also a class with name Teacher.

I know both of them have some properties in common e.g DateOfBirth so I have an interface called: ISchoolMember that has:

DateTime? DateOfBirth {get; set;}

If both Student and Teacher implement my ISchoolMember interface, I can now create an ObservableCollection (or even better, ObservableRangeCollection) of type ISchoolMember so in this way I can have Student, Teacher or any other type that implements my interface in it.

When I need Students only I can use OfType<Student>() in a LINQ query.

Upvotes: 0

Philipp Seif
Philipp Seif

Reputation: 1

I created a separate class Device

public class Device
{

    public Device(String arg_DeviceName)
    {
        DeviceName = arg_DeviceName;
    }


    public String DeviceName { get; }

    public ObservableCollection<DeviceItem> Items
    {
        get; set;
    }
}

And than I solved it like this:

public Device CellPhones{ get; set; }

public ObservableCollection<DeviceItem> CellPhoneItems
{
    get; set;
}

public Device Watches { get; set; }

public ObservableCollection<DeviceItem> WatchItems
{
    get; set;
}

public ObservableCollection<Device> Devices
{
    get; set;
}



CellPhones = new Device("Cells");
CellPhoneItems = new ObservableCollection<DeviceItem>();
Watches = new Device("Watch");
WatchItems = new ObservableCollection<DeviceItem>();
CellPhones.Items = CellPhoneItems;
Watches.Items = WatchItems;
Devices = new ObservableCollection<Device>();
Devices.Add(CellPhones);
Devices.Add(Watches);

With this I can bind to the Items-Property of the Device-class.

Thank you HimBromBeere. You opened my eyes and pushed me towards the solution.

Upvotes: 0

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

A List<Derived> simply is not a List<Base>, even if a Derived is a Base. The same applies to an ObservableCollection. In other words: if this were allowed, you could put both, List<CellPhone> and List<Watch> into your list at the same time. How would any user know what items he actually has in his list:

var a = Devices[0]; // what type has a here? compiler can´t infer that type

Why not simply make Watches and CellPhones an ObservableCollection<DeviceItem> in the first place:

public ObservableCollection<DeviceItem> CellPhones { get; set; }    
public ObservableCollection<DeviceItem> Watches { get; set; }    
public ObservableCollection<ObservableCollection<DeviceItem>> Devices { get; set; }

Now you can easily do this:

Devices.Add(CellPhones);
Devices.Add(Watches);

Upvotes: 2

Related Questions