Skip to content

Instantly share code, notes, and snippets.

@dealproc
Created January 16, 2015 14:15
Show Gist options
  • Save dealproc/bf94315ca4560db3f63f to your computer and use it in GitHub Desktop.
Save dealproc/bf94315ca4560db3f63f to your computer and use it in GitHub Desktop.
MahApps.Metro & Caliburn Micro DialogViewManager Implementation .. basis was from someone else, but I had to re-tool it to work the way i wanted. It seems as if full binding is working as expected as well using the CM pipeline :)
using {Product}.UX.ViewModels.Framework;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace {Product}.UX.Services {
public class DialogManager : IDialogManager {
public static readonly MetroDialogSettings dialogSettings = new MetroDialogSettings {
AnimateShow = false,
AnimateHide = false
};
public async Task ShowDialog(DialogViewModel viewModel) {
var dialog = ViewLocator.LocateForModel(viewModel, null, null) as BaseMetroDialog;
MetroWindow firstMetroWindow = Application.Current.Windows.OfType<MetroWindow>().First();
ViewModelBinder.Bind(viewModel, dialog, firstMetroWindow);
await firstMetroWindow.ShowMetroDialogAsync(dialog, dialogSettings);
dialog.Focus();
viewModel.OnActivate();
await viewModel.Task;
viewModel.OnDeactivate();
await firstMetroWindow.HideMetroDialogAsync(dialog, dialogSettings);
}
public async Task<TResult> ShowDialog<TResult>(DialogViewModel<TResult> viewModel) {
var dialog = ViewLocator.LocateForModel(viewModel, null, null) as BaseMetroDialog;
MetroWindow firstMetroWindow = Application.Current.Windows.OfType<MetroWindow>().First();
ViewModelBinder.Bind(viewModel, dialog, firstMetroWindow);
await firstMetroWindow.ShowMetroDialogAsync(dialog, dialogSettings);
dialog.Focus();
viewModel.OnActivate();
TResult result = await viewModel.Task;
viewModel.OnDeactivate();
await firstMetroWindow.HideMetroDialogAsync(dialog, dialogSettings);
return result;
}
public async Task<TResult> ShowChildDialog<TResult>(DialogViewModel<TResult> viewModel, object parentContext) {
// Locate Parent Dialog.
MetroWindow firstMetroWindow = Application.Current.Windows.OfType<MetroWindow>().First();
BaseMetroDialog parentDialog;
if (parentContext is IViewAware) {
parentDialog = ViewLocator.LocateForModel(parentContext, firstMetroWindow, null) as BaseMetroDialog;
} else {
parentDialog = ViewLocator.LocateForModelType(parentContext.GetType(), firstMetroWindow, null) as BaseMetroDialog;
}
// Hide Parent Dialog.
await firstMetroWindow.HideMetroDialogAsync(parentDialog, dialogSettings);
// Show child dialog.
var result = await ShowDialog(viewModel);
// re-show the main dialog.
await firstMetroWindow.ShowMetroDialogAsync(parentDialog, dialogSettings);
// return the result
return result;
}
public async Task ShowChildDialog(DialogViewModel viewModel, object parentContext) {
// Locate Parent Dialog.
MetroWindow firstMetroWindow = Application.Current.Windows.OfType<MetroWindow>().First();
BaseMetroDialog parentDialog;
if (parentContext is IViewAware) {
parentDialog = ViewLocator.LocateForModel(parentContext, firstMetroWindow, null) as BaseMetroDialog;
} else {
parentDialog = ViewLocator.LocateForModelType(parentContext.GetType(), firstMetroWindow, null) as BaseMetroDialog;
}
// Hide Parent Dialog.
await firstMetroWindow.HideMetroDialogAsync(parentDialog, dialogSettings);
// Show child dialog.
await ShowDialog(viewModel);
// re-show the main dialog.
await firstMetroWindow.ShowMetroDialogAsync(parentDialog, dialogSettings);
}
}
}
using Caliburn.Micro;
using System;
using System.Threading.Tasks;
namespace {Product}.UX.ViewModels.Framework {
public abstract class DialogViewModel : PropertyChangedBase, IViewAware, IHaveDisplayName, IDialogViewModel {
protected readonly TaskCompletionSource<int> _TaskCompletionSource;
protected object _View;
protected object _Context;
string _DisplayName;
public Task Task {
get { return _TaskCompletionSource.Task; }
}
public string DisplayName {
get { return _DisplayName; }
set {
_DisplayName = value;
NotifyOfPropertyChange(() => DisplayName);
NotifyOfPropertyChange(() => Title);
}
}
public string Title {
get { return DisplayName; }
}
public DialogViewModel() {
_TaskCompletionSource = new TaskCompletionSource<int>();
}
public virtual void OnActivate() { }
public virtual void OnDeactivate() { }
protected void Close() {
_TaskCompletionSource.SetResult(0);
var handler = Closed;
if (handler != null) {
handler(this, EventArgs.Empty);
}
}
public event EventHandler Closed;
public void AttachView(object view, object context = null) {
_View = view;
_Context = context;
}
public object GetView(object context = null) {
return _View;
}
public event EventHandler<ViewAttachedEventArgs> ViewAttached;
}
public abstract class TouchDialogViewModel<TFieldEnum> : DialogViewModel {
TFieldEnum _CurrentField;
public TFieldEnum CurrentField {
get { return _CurrentField; }
set {
_CurrentField = value;
NotifyOfPropertyChange(() => CurrentField);
}
}
public virtual void SetFocused(TFieldEnum field) {
CurrentField = field;
}
}
public abstract class DialogViewModel<TResult> : PropertyChangedBase, IViewAware, IHaveDisplayName, IDialogViewModel {
protected object _View;
protected object _Context;
protected TaskCompletionSource<TResult> _TaskCompletionSource;
string _DisplayName;
public Task<TResult> Task {
get { return _TaskCompletionSource.Task; }
}
public string DisplayName {
get { return _DisplayName; }
set {
_DisplayName = value;
NotifyOfPropertyChange(() => Title);
}
}
public string Title {
get { return DisplayName; }
}
public DialogViewModel() {
_TaskCompletionSource = new TaskCompletionSource<TResult>();
}
public virtual void OnActivate() { }
public virtual void OnDeactivate() { }
protected void Close(TResult result) {
_TaskCompletionSource.SetResult(result);
var handler = Closed;
if (handler != null) {
handler(this, EventArgs.Empty);
}
}
public event EventHandler Closed;
public void AttachView(object view, object context = null) {
_View = view;
_Context = context;
}
public object GetView(object context = null) {
return _View;
}
public event EventHandler<ViewAttachedEventArgs> ViewAttached;
}
public abstract class TouchDialogViewModel<TResult, TFieldEnum> : DialogViewModel<TResult> {
TFieldEnum _CurrentField;
public TFieldEnum CurrentField {
get { return _CurrentField; }
set {
_CurrentField = value;
NotifyOfPropertyChange(() => CurrentField);
}
}
public virtual void SetFocused(TFieldEnum field) {
CurrentField = field;
}
}
}
using {Product}.UX.ViewModels.Framework;
using System.Threading.Tasks;
namespace {Product}.UX.Services {
public interface IDialogManager {
Task<TResult> ShowDialog<TResult>(DialogViewModel<TResult> viewModel);
Task ShowDialog(DialogViewModel viewModel);
Task<TResult> ShowChildDialog<TResult>(DialogViewModel<TResult> viewModel, object parentContext);
Task ShowChildDialog(DialogViewModel viewModel, object parentContext);
}
}
using System;
namespace {Product}.UX.ViewModels.Framework {
public interface IDialogViewModel {
event EventHandler Closed;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment