The progress spinner can now tell its optimal size required to show the entire status text but overlap as few controls as possible; began implementing a generic version of a multi page view model and matching view with caching
git-svn-id: file:///srv/devel/repo-conversion/nuwi@53 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
17ec2d0f69
commit
91432c5209
5 changed files with 390 additions and 3 deletions
14
Source/ViewModels/IMultiPageViewModel.cs
Normal file
14
Source/ViewModels/IMultiPageViewModel.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace Nuclex.Windows.Forms.ViewModels {
|
||||
|
||||
/// <summary>Interface for vew models that can switch between different pages</summary>
|
||||
public interface IMultiPageViewModel {
|
||||
|
||||
/// <summary>Retrieves (and, if needed, creates) the view model for the active page</summary>
|
||||
/// <returns>A view model for the active page on the multi-page view model</returns>
|
||||
object GetActivePageViewModel();
|
||||
|
||||
}
|
||||
|
||||
} // namespace Nuclex.Windows.Forms.ViewModels
|
|
@ -19,6 +19,7 @@ License along with this library
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using Nuclex.Support;
|
||||
|
||||
|
@ -26,8 +27,8 @@ namespace Nuclex.Windows.Forms.ViewModels {
|
|||
|
||||
/// <summary>Base class for view models that have multiple child view models</summary>
|
||||
/// <typeparam name="TPageEnumeration">Enum type by which pages can be indicated</typeparam>
|
||||
public abstract class MultiPageViewModel<TPageEnumeration> : Observable
|
||||
where TPageEnumeration : IEquatable<TPageEnumeration> {
|
||||
public abstract class MultiPageViewModel<TPageEnumeration> :
|
||||
Observable, IMultiPageViewModel, IDisposable {
|
||||
|
||||
/// <summary>Initializes a new multi-page view model</summary>
|
||||
/// <param name="windowManager">
|
||||
|
@ -38,6 +39,25 @@ namespace Nuclex.Windows.Forms.ViewModels {
|
|||
/// </param>
|
||||
public MultiPageViewModel(IWindowManager windowManager, bool cachePageViewModels = false) {
|
||||
this.windowManager = windowManager;
|
||||
if(cachePageViewModels) {
|
||||
this.cachedViewModels = new ConcurrentDictionary<TPageEnumeration, object>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Immediately releases all resources owned by the instance</summary>
|
||||
public virtual void Dispose() {
|
||||
if(this.cachedViewModels != null) {
|
||||
foreach(object cacheViewModel in this.cachedViewModels.Values) {
|
||||
disposeIfSupported(cacheViewModel);
|
||||
}
|
||||
this.activePageViewModel = null;
|
||||
|
||||
this.cachedViewModels.Clear();
|
||||
this.cachedViewModels = null;
|
||||
} else if(this.activePageViewModel != null) {
|
||||
disposeIfSupported(this.activePageViewModel);
|
||||
this.activePageViewModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Child page that is currently being displayed by the view model</summary>
|
||||
|
@ -46,11 +66,36 @@ namespace Nuclex.Windows.Forms.ViewModels {
|
|||
set {
|
||||
if(!this.activePage.Equals(value)) {
|
||||
this.activePage = value;
|
||||
if(this.activePageViewModel != null) {
|
||||
if(this.cachedViewModels == null) {
|
||||
disposeIfSupported(this.activePageViewModel);
|
||||
}
|
||||
this.activePageViewModel = null;
|
||||
}
|
||||
OnPropertyChanged(nameof(ActivePage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Retrieves (and, if needed, creates) the view model for the active page</summary>
|
||||
/// <returns>A view model for the active page on the multi-page view model</returns>
|
||||
public object GetActivePageViewModel() {
|
||||
if(this.cachedViewModels == null) {
|
||||
if(this.activePageViewModel == null) {
|
||||
this.activePageViewModel = CreateViewModelForPage(this.activePage);
|
||||
}
|
||||
} else if(this.activePageViewModel == null) {
|
||||
this.activePageViewModel = this.cachedViewModels.GetOrAdd(
|
||||
this.activePage,
|
||||
delegate(TPageEnumeration activePage) {
|
||||
return CreateViewModelForPage(this.activePage);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return this.activePageViewModel;
|
||||
}
|
||||
|
||||
/// <summary>Windowmanager that can create view models and display other views</summary>
|
||||
protected IWindowManager WindowManager {
|
||||
get { return this.windowManager; }
|
||||
|
@ -59,13 +104,27 @@ namespace Nuclex.Windows.Forms.ViewModels {
|
|||
/// <summary>Creates a view model for the specified page</summary>
|
||||
/// <param name="page">Page for which a view model will be created</param>
|
||||
/// <returns>The view model for the specified page</returns>
|
||||
protected abstract object createViewModelForPage(TPageEnumeration page);
|
||||
protected abstract object CreateViewModelForPage(TPageEnumeration page);
|
||||
|
||||
/// <summary>Disposes the specified object if it is disposable</summary>
|
||||
/// <param name="potentiallyDisposable">Object that will be disposed if supported</param>
|
||||
private static void disposeIfSupported(object potentiallyDisposable) {
|
||||
var disposable = potentiallyDisposable as IDisposable;
|
||||
if(disposable != null) {
|
||||
disposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Page that is currently active in the multi-page view model</summary>
|
||||
private TPageEnumeration activePage;
|
||||
/// <summary>Window manager that can be used to display other views</summary>
|
||||
private IWindowManager windowManager;
|
||||
|
||||
/// <summary>View model for the active page</summary>
|
||||
private object activePageViewModel;
|
||||
/// <summary>Cached page view models, if caching is enabled</summary>
|
||||
private ConcurrentDictionary<TPageEnumeration, object> cachedViewModels;
|
||||
|
||||
}
|
||||
|
||||
} // namespace Nuclex.Windows.Forms.ViewModels
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue