using System; using System.Linq; using System.Linq.Expressions; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using DevExpress.Mvvm; using DevExpress.Mvvm.POCO; using DevExpress.Mvvm.DataAnnotations; using System.Collections.ObjectModel; using System.Threading; using System.Threading.Tasks; using DevExpress.DevAV.Common.Utils; using DevExpress.Mvvm.DataModel; namespace DevExpress.DevAV.Common.ViewModel { /// /// The base class for POCO view models exposing a read-only collection of entities of a given type. /// This is a partial class that provides the extension point to add custom properties, commands and override methods without modifying the auto-generated code. /// /// An entity type. /// A unit of work type. public partial class ReadOnlyCollectionViewModel : ReadOnlyCollectionViewModel where TEntity : class where TUnitOfWork : IUnitOfWork { /// /// Creates a new instance of ReadOnlyCollectionViewModel as a POCO view model. /// /// A factory used to create a unit of work instance. /// A function that returns a repository representing entities of the given type. /// An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data. public static ReadOnlyCollectionViewModel CreateReadOnlyCollectionViewModel( IUnitOfWorkFactory unitOfWorkFactory, Func> getRepositoryFunc, Func, IQueryable> projection = null) { return ViewModelSource.Create(() => new ReadOnlyCollectionViewModel(unitOfWorkFactory, getRepositoryFunc, projection)); } /// /// Initializes a new instance of the ReadOnlyCollectionViewModel class. /// This constructor is declared protected to avoid an undesired instantiation of the PeekCollectionViewModel type without the POCO proxy factory. /// /// A factory used to create a unit of work instance. /// A function that returns a repository representing entities of the given type. /// An optional parameter that provides a LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data. protected ReadOnlyCollectionViewModel( IUnitOfWorkFactory unitOfWorkFactory, Func> getRepositoryFunc, Func, IQueryable> projection = null) : base(unitOfWorkFactory, getRepositoryFunc, projection) { } } /// /// The base class for POCO view models exposing a read-only collection of entities of a given type. /// This is a partial class that provides the extension point to add custom properties, commands and override methods without modifying the auto-generated code. /// /// A repository entity type. /// A projection entity type. /// A unit of work type. public partial class ReadOnlyCollectionViewModel : ReadOnlyCollectionViewModelBase where TEntity : class where TProjection : class where TUnitOfWork : IUnitOfWork { /// /// Creates a new instance of ReadOnlyCollectionViewModel as a POCO view model. /// /// A factory used to create a unit of work instance. /// A function that returns the repository representing entities of a given type. /// A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type. public static ReadOnlyCollectionViewModel CreateReadOnlyProjectionCollectionViewModel( IUnitOfWorkFactory unitOfWorkFactory, Func> getRepositoryFunc, Func, IQueryable> projection) { return ViewModelSource.Create(() => new ReadOnlyCollectionViewModel(unitOfWorkFactory, getRepositoryFunc, projection)); } /// /// Initializes a new instance of the ReadOnlyCollectionViewModel class. /// This constructor is declared protected to avoid an undesired instantiation of the PeekCollectionViewModel type without the POCO proxy factory. /// /// A factory used to create a unit of work instance. /// A function that returns the repository representing entities of a given type. /// A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type. protected ReadOnlyCollectionViewModel( IUnitOfWorkFactory unitOfWorkFactory, Func> getRepositoryFunc, Func, IQueryable> projection) : base(unitOfWorkFactory, getRepositoryFunc, projection) { } } /// /// The base class for POCO view models exposing a read-only collection of entities of a given type. /// It is not recommended to inherit directly from this class. Use the ReadOnlyCollectionViewModel class instead. /// /// A repository entity type. /// A projection entity type. /// A unit of work type. [POCOViewModel] public abstract class ReadOnlyCollectionViewModelBase : EntitiesViewModel where TEntity : class where TProjection : class where TUnitOfWork : IUnitOfWork { /// /// Initializes a new instance of the ReadOnlyCollectionViewModelBase class. /// /// A factory used to create a unit of work instance. /// A function that returns the repository representing entities of a given type. /// A LINQ function used to customize a query for entities. The parameter, for example, can be used for sorting data and/or for projecting data to a custom type that does not match the repository entity type. protected ReadOnlyCollectionViewModelBase( IUnitOfWorkFactory unitOfWorkFactory, Func> getRepositoryFunc, Func, IQueryable> projection ) : base(unitOfWorkFactory, getRepositoryFunc, projection) { } /// /// The selected enity. /// Since ReadOnlyCollectionViewModelBase is a POCO view model, this property will raise INotifyPropertyChanged.PropertyEvent when modified so it can be used as a binding source in views. /// public virtual TProjection SelectedEntity { get; set; } /// /// The lambda expression used to filter which entities will be loaded locally from the unit of work. /// Since ReadOnlyCollectionViewModelBase is a POCO view model, this property will raise INotifyPropertyChanged.PropertyEvent when modified so it can be used as a binding source in views. /// public virtual Expression> FilterExpression { get; set; } /// /// Reloads entities. /// Since CollectionViewModelBase is a POCO view model, an instance of this class will also expose the RefreshCommand property that can be used as a binding source in views. /// public virtual void Refresh() { LoadEntities(false); } /// /// Determines whether entities can be reloaded. /// Since CollectionViewModelBase is a POCO view model, this method will be used as a CanExecute callback for RefreshCommand. /// public bool CanRefresh() { return !IsLoading; } protected override void OnEntitiesAssigned(Func getSelectedEntityCallback) { base.OnEntitiesAssigned(getSelectedEntityCallback); SelectedEntity = getSelectedEntityCallback() ?? Entities.FirstOrDefault(); } protected override Func GetSelectedEntityCallback() { int selectedItemIndex = Entities.IndexOf(SelectedEntity); return () => (selectedItemIndex >= 0 && selectedItemIndex < Entities.Count) ? Entities[selectedItemIndex] : null; } protected override void OnIsLoadingChanged() { base.OnIsLoadingChanged(); this.RaiseCanExecuteChanged(x => x.Refresh()); } protected virtual void OnSelectedEntityChanged() { } protected virtual void OnFilterExpressionChanged() { if(IsLoaded || IsLoading) LoadEntities(true); } protected override Expression> GetFilterExpression() { return FilterExpression; } } }