I have the following code :
public abstract class ListPresenter<TView, TModel, TEntity> : Presenter<TView, TModel>
where TView : IListView<TModel>
where TModel : EntityListViewModel<TEntity>
where TEntity : class, IEntity
{
public ListPresenter(TView view, TModel model)
: base(view, model)
{
}
}
Is there any way to avoid the third parameter? If I try to use :
public abstract class ListPresenter<TView, TModel> : Presenter<TView, TModel>
where TView : IListView<TModel>
where TModel : EntityListViewModel<IEntity>
I get:
Error 3 The type 'PuntoVenta.ViewModels.SaleListViewModel' cannot be used as type parameter 'TModel' in the generic type or method 'PuntoVenta.Presentation.ListPresenter'. There is no implicit reference conversion from 'PuntoVenta.ViewModels.SaleListViewModel' to 'PuntoVenta.ViewModels.EntityListViewModel'. C:\Users\Marc\Dropbox\Source\PointOfSale\PuntoVenta\Presentation\ListSalePresenter.cs 26 20 PuntoVenta.UI
even EntityListViewModel< IEntity > will always be true.
public abstract class EntityListViewModel<TEntity> : ViewModelBase, IEntityListViewModel<TEntity>
where TEntity : class, IEntity
{
private BindingSource Entities { get; set; }
private string searchQuery = string.Empty;
public EntityListViewModel()
{
SearchQuery = string.Empty;
Entities = new BindingSource();
}
public TEntity Selected
{
get { return Entities.Current as TEntity; }
set { Entities.Position = Entities.IndexOf(value); }
}
public string SearchQuery
{
get { return searchQuery; }
set
{
searchQuery = value;
NotifyProperty("SearchQuery");
}
}
public List<TEntity> DataSource
{
set
{
Entities.DataSource = value;
NotifyProperty("DataSource");
}
}
}
public interface IEntity
{
Guid Id { get; set; }
DateTime DateCreated { get; set; }
DateTime DateUpdated { get; set; }
}
public interface IListView<TModel> : IView<TModel>
where TModel : ViewModelBase
{
event EventHandler OnSearchQueryChanged;
event EventHandler OnSelectRequested;
}
public abstract class ViewModelBase : IModel
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyProperty(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SaleListViewModel : EntityListViewModel<SaleView>
{
private bool _ShowPendingOnly = false;
public SaleListViewModel()
{
}
public bool ShowPendingOnly
{
get { return _ShowPendingOnly; }
set
{
_ShowPendingOnly = value;
NotifyProperty("ShowPendingOnly");
}
}
public List<Customer> Customers { get; set; }
}
Avoid to use generic type on declaration of EntityListViewModel
.
There is no need of declare with generics in this case whether the objects always implement IEntity
interface.
public abstract class EntityListViewModel
: ViewModelBase, IEntityListViewModel<IEntity>
You also need to change any reference in this class to TEntity
.
public IEntity Selected
{
get { return Entities.Current as IEntity; }
set { Entities.Position = Entities.IndexOf(value); }
}
public List<IEntity> DataSource
{
set
{
Entities.DataSource = value;
NotifyProperty("DataSource");
}
}
At this point, you can declare ListPresenter
as
public abstract class ListPresenter<TView, TModel>
: Presenter<TView, TModel>
where TView : IListView<TModel>
where TModel : EntityListViewModel<IEntity>