Reputation: 1
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
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
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
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