I have classes and interfaces:
public interface IEntity { int ID { get; set; } } public class Entity : IEntity { public int ID { get; set; } } public interface IEntityListViewModel { RangeObservableCollection<IEntity> Items { get; set; } IEntity SelectedItem { get; set; } void LoadItems(); } Now I need this class:
public abstract class EntityListViewModel<T> : IEntityListViewModel where T : IEntity { public RangeObservableCollection<T> Items { get; set; } public T SelectedItem { get; set; } public EntityListViewModel() { Items = new RangeObservableCollection<T>(); } protected abstract List<T> GetEntities(); public void LoadItems() { var lst = GetEntities(); Items.ReplaceRange(lst); } } Naturally, the compiler requires the implementation of RangeObservableCollection.Items
I could do this:
public interface IEntityListViewModel<T> where T : IEntity { RangeObservableCollection<T> Items { get; set; } T SelectedItem { get; set; } void LoadItems(); } But I have another class:
public abstract class UserControlBase : UserControl { public IEntityListViewModel VM { get; set; } public virtual void Page_Loaded(object sender, RoutedEventArgs e) { VM.LoadItems(); } } And then specific UserControls are inherited from UserControlBase. What is it for me? In UserControls, a bunch of duplicate code (mostly binding to ViewModel events). Therefore, all I want to do in UserControlBase. I could declare in UserControlBase like this:
public IEntityListViewModel<T> VM { get; set; } but then I need to raise T in UserControlBase, but this is somehow crooked.
How do I inherit an EntityListViewModel from a regular IEntityListViewModel? Or is there some other solution?
UPD 1: Explicitly implemented, as advised in the comments:
public abstract class EntityListViewModel<T> : IEntityListViewModel where T : IEntity { public RangeObservableCollection<T> Items { get; set; } public T SelectedItem { get; set; } RangeObservableCollection<IEntity> IEntityListViewModel.Items { get; set; } IEntity IEntityListViewModel.SelectedItem { get; set; } public EntityListViewModel() { Items = new RangeObservableCollection<T>(); } protected abstract List<T> GetEntities(); public void LoadItems() { var lst = GetEntities(); Items.ReplaceRange(lst); } } But now in View, the VM.Items call is called IEntityListViewModel.Items