Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions MahApps.Metro/Controls/Dialogs/DialogCoordinator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using System.Threading.Tasks;
using System.Windows;

namespace MahApps.Metro.Controls.Dialogs
{
public class DialogCoordinator : IDialogCoordinator
{
/// <summary>
/// Gets the default instance if the dialog coordinator, which can be injected into a view model.
/// </summary>
public static readonly DialogCoordinator Instance = new DialogCoordinator();

public Task<string> ShowInputAsync(object context, string title, string message, MetroDialogSettings metroDialogSettings = null)
{
var metroWindow = GetMetroWindow(context);

return metroWindow.ShowInputAsync(title, message, metroDialogSettings);
}

public Task<LoginDialogData> ShowLoginAsync(object context, string title, string message, MessageDialogStyle style = MessageDialogStyle.Affirmative, LoginDialogSettings settings = null)
{
var metroWindow = GetMetroWindow(context);

return metroWindow.ShowLoginAsync(title, message, settings);
}

public Task<MessageDialogResult> ShowMessageAsync(object context, string title, string message, MessageDialogStyle style = MessageDialogStyle.Affirmative, MetroDialogSettings settings = null)
{
var metroWindow = GetMetroWindow(context);

return metroWindow.ShowMessageAsync(title, message, style, settings);
}

public Task<ProgressDialogController> ShowProgressAsync(object context, string title, string message,
bool isCancelable = false, MetroDialogSettings settings = null)
{
var metroWindow = GetMetroWindow(context);

return metroWindow.ShowProgressAsync(title, message, isCancelable, settings);
}

public Task ShowMetroDialogAsync(object context, BaseMetroDialog dialog,
MetroDialogSettings settings = null)
{
var metroWindow = GetMetroWindow(context);

return metroWindow.ShowMetroDialogAsync(dialog, settings);
}

public Task HideMetroDialogAsync(object context, BaseMetroDialog dialog, MetroDialogSettings settings = null)
{
var metroWindow = GetMetroWindow(context);

return metroWindow.HideMetroDialogAsync(dialog, settings);
}

public Task<TDialog> GetCurrentDialogAsync<TDialog>(object context) where TDialog : BaseMetroDialog
{
var metroWindow = GetMetroWindow(context);

return metroWindow.GetCurrentDialogAsync<TDialog>();
}

private static MetroWindow GetMetroWindow(object context)
{
if (context == null) throw new ArgumentNullException("context");
if (!DialogParticipation.IsRegistered(context))
throw new InvalidOperationException(
"Context is not registered. Consider using DialogParticipation.Register in XAML to bind in the DataContext.");

var association = DialogParticipation.GetAssociation(context);
var metroWindow = Window.GetWindow(association) as MetroWindow;

if (metroWindow == null)
throw new InvalidOperationException("Control is not inside a MetroWindow.");
return metroWindow;
}
}
}
47 changes: 47 additions & 0 deletions MahApps.Metro/Controls/Dialogs/DialogParticipation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Windows;

namespace MahApps.Metro.Controls.Dialogs
{
public static class DialogParticipation
{
private static readonly IDictionary<object, DependencyObject> ContextRegistrationIndex = new Dictionary<object, DependencyObject>();

public static readonly DependencyProperty RegisterProperty = DependencyProperty.RegisterAttached(
"Register", typeof(object), typeof(DialogParticipation), new PropertyMetadata(default(object), RegisterPropertyChangedCallback));

private static void RegisterPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (dependencyPropertyChangedEventArgs.OldValue != null)
ContextRegistrationIndex.Remove(dependencyPropertyChangedEventArgs.OldValue);

if (dependencyPropertyChangedEventArgs.NewValue != null)
ContextRegistrationIndex[dependencyPropertyChangedEventArgs.NewValue] = dependencyObject;
}

public static void SetRegister(DependencyObject element, object context)
{
element.SetValue(RegisterProperty, context);
}

public static object GetRegister(DependencyObject element)
{
return element.GetValue(RegisterProperty);
}

internal static bool IsRegistered(object context)
{
if (context == null) throw new ArgumentNullException("context");

return ContextRegistrationIndex.ContainsKey(context);
}

internal static DependencyObject GetAssociation(object context)
{
if (context == null) throw new ArgumentNullException("context");

return ContextRegistrationIndex[context];
}
}
}
86 changes: 86 additions & 0 deletions MahApps.Metro/Controls/Dialogs/IDialogCoordinator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.Threading.Tasks;

namespace MahApps.Metro.Controls.Dialogs
{
/// <summary>
/// Use the dialog coordinator to help you interfact with dialogs from a view model.
/// </summary>
public interface IDialogCoordinator
{
/// <summary>
/// Shows the input dialog.
/// </summary>
/// <param name="context">Typically this should be the view model, which you register in XAML using <see cref="DialogParticipation.SetRegister"/>.</param>
/// <param name="title">The title of the MessageDialog.</param>
/// <param name="message">The message contained within the MessageDialog.</param>
/// <param name="settings">Optional settings that override the global metro dialog settings.</param>
/// <returns>The text that was entered or null (Nothing in Visual Basic) if the user cancelled the operation.</returns>
Task<string> ShowInputAsync(object context, string title, string message, MetroDialogSettings settings = null);

/// <summary>
/// Creates a LoginDialog inside of the current window.
/// </summary>
/// <param name="context">Typically this should be the view model, which you register in XAML using <see cref="DialogParticipation.SetRegister"/>.</param>
/// <param name="title">The title of the LoginDialog.</param>
/// <param name="message">The message contained within the LoginDialog.</param>
/// <param name="style"></param>
/// <param name="settings">Optional settings that override the global metro dialog settings.</param>
/// <returns>The text that was entered or null (Nothing in Visual Basic) if the user cancelled the operation.</returns>
Task<LoginDialogData> ShowLoginAsync(object context, string title, string message, MessageDialogStyle style = MessageDialogStyle.Affirmative, LoginDialogSettings settings = null);

/// <summary>
/// Creates a MessageDialog inside of the current window.
/// </summary>
/// <param name="context">Typically this should be the view model, which you register in XAML using <see cref="DialogParticipation.SetRegister"/>.</param>
/// <param name="title">The title of the MessageDialog.</param>
/// <param name="message">The message contained within the MessageDialog.</param>
/// <param name="style">The type of buttons to use.</param>
/// <param name="settings">Optional settings that override the global metro dialog settings.</param>
/// <returns>A task promising the result of which button was pressed.</returns>
Task<MessageDialogResult> ShowMessageAsync(object context, string title, string message, MessageDialogStyle style = MessageDialogStyle.Affirmative, MetroDialogSettings settings = null);

/// <summary>
/// Creates a ProgressDialog inside of the current window.
/// </summary>
/// <param name="context">Typically this should be the view model, which you register in XAML using <see cref="DialogParticipation.SetRegister"/>.</param>
/// <param name="title">The title of the ProgressDialog.</param>
/// <param name="message">The message within the ProgressDialog.</param>
/// <param name="isCancelable">Determines if the cancel button is visible.</param>
/// <param name="settings">Optional Settings that override the global metro dialog settings.</param>
/// <returns>A task promising the instance of ProgressDialogController for this operation.</returns>
Task<ProgressDialogController> ShowProgressAsync(object context, string title, string message,
bool isCancelable = false, MetroDialogSettings settings = null);

/// <summary>
/// Adds a Metro Dialog instance to the specified window and makes it visible asynchronously.
/// <para>You have to close the resulting dialog yourself with <see cref="HideMetroDialogAsync"/>.</para>
/// </summary>
/// <param name="context">Typically this should be the view model, which you register in XAML using <see cref="DialogParticipation.SetRegister"/>.</param>
/// <param name="dialog">The dialog instance itself.</param>
/// <param name="settings">An optional pre-defined settings instance.</param>
/// <returns>A task representing the operation.</returns>
/// <exception cref="InvalidOperationException">The <paramref name="dialog"/> is already visible in the window.</exception>
Task ShowMetroDialogAsync(object context, BaseMetroDialog dialog,
MetroDialogSettings settings = null);

/// <summary>
/// Hides a visible Metro Dialog instance.
/// </summary>
/// <param name="context">Typically this should be the view model, which you register in XAML using <see cref="DialogParticipation.SetRegister"/>.</param>
/// <param name="dialog">The dialog instance to hide.</param>
/// <param name="settings">An optional pre-defined settings instance.</param>
/// <returns>A task representing the operation.</returns>
/// <exception cref="InvalidOperationException">
/// The <paramref name="dialog"/> is not visible in the window.
/// This happens if <see cref="ShowMetroDialogAsync"/> hasn't been called before.
/// </exception>
Task HideMetroDialogAsync(object context, BaseMetroDialog dialog, MetroDialogSettings settings = null);

/// <summary>
/// Gets the current shown dialog.
/// </summary>
/// <param name="context">Typically this should be the view model, which you register in XAML using <see cref="DialogParticipation.SetRegister"/>.</param>
Task<TDialog> GetCurrentDialogAsync<TDialog>(object context) where TDialog : BaseMetroDialog;
}
}
3 changes: 3 additions & 0 deletions MahApps.Metro/MahApps.Metro.NET45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@
<Compile Include="Behaviours\StylizedBehaviorCollection.cs" />
<Compile Include="Behaviours\TabControlSelectFirstVisibleTabBehavior.cs" />
<Compile Include="Behaviours\WindowsSettingBehaviour.cs" />
<Compile Include="Controls\Dialogs\DialogCoordinator.cs" />
<Compile Include="Controls\Dialogs\DialogParticipation.cs" />
<Compile Include="Controls\Dialogs\IDialogCoordinator.cs" />
<Compile Include="Controls\Helper\ButtonHelper.cs" />
<Compile Include="Controls\ClosingWindowEventHandlerArgs.cs" />
<Compile Include="Controls\Helper\ComboBoxHelper.cs" />
Expand Down
3 changes: 3 additions & 0 deletions MahApps.Metro/MahApps.Metro.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
<Compile Include="Actions\SetFlyoutOpenAction.cs" />
<Compile Include="Behaviours\BindableResourceBehavior.cs" />
<Compile Include="Behaviours\BorderlessWindowBehavior.cs" />
<Compile Include="Controls\Dialogs\DialogCoordinator.cs" />
<Compile Include="Controls\Dialogs\DialogParticipation.cs" />
<Compile Include="Behaviours\GlowWindowBehavior.cs" />
<Compile Include="Behaviours\PasswordBoxBindingBehavior.cs" />
<Compile Include="Behaviours\StylizedBehaviorCollection.cs" />
Expand All @@ -95,6 +97,7 @@
<Compile Include="Controls\Dialogs\BaseMetroDialog.cs" />
<Compile Include="Controls\Dialogs\DialogManager.cs" />
<Compile Include="Controls\Dialogs\DialogStateChangedEventArgs.cs" />
<Compile Include="Controls\Dialogs\IDialogCoordinator.cs" />
<Compile Include="Controls\Dialogs\InputDialog.cs" />
<Compile Include="Controls\Dialogs\LoginDialog.cs" />
<Compile Include="Controls\Dialogs\ProgressDialog.cs" />
Expand Down
3 changes: 2 additions & 1 deletion samples/MetroDemo/ExampleWindows/FlyoutDemo.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Windows;
using System.Windows.Input;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using MetroDemo.Models;

namespace MetroDemo.ExampleWindows
Expand All @@ -13,7 +14,7 @@ public partial class FlyoutDemo : IDisposable

public FlyoutDemo()
{
this.DataContext = new MainWindowViewModel();
this.DataContext = new MainWindowViewModel(DialogCoordinator.Instance);
this.InitializeComponent();
this.Closing += (s, e) =>
{
Expand Down
15 changes: 14 additions & 1 deletion samples/MetroDemo/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
d:DesignHeight="600"
d:DesignWidth="800"
d:DataContext="{d:DesignInstance MetroDemo:MainWindowViewModel}"
Closing="MetroWindow_Closing">
Closing="MetroWindow_Closing"
Dialog:DialogParticipation.Register="{Binding}"
>

<Window.Resources>
<ResourceDictionary>
Expand Down Expand Up @@ -178,6 +180,17 @@
Header="Show CustomDialog Externally" />
<MenuItem Click="ShowAwaitCustomDialog"
Header="Await CustomDialog" />
<Separator />
<MenuItem Command="{Binding ShowInputDialogCommand}"
Header="Show InputDialog via VM" />
<MenuItem Command="{Binding ShowLoginDialogCommand}"
Header="Show LoginDialog via VM" />
<MenuItem Command="{Binding ShowMessageDialogCommand}"
Header="Show MessageDialog via VM" />
<MenuItem Command="{Binding ShowProgressDialogCommand}"
Header="Show ProgressDialog via VM" />
<MenuItem Command="{Binding ShowCustomDialogCommand}"
Header="Show CustomDialog via VM" />
</MenuItem>
<MenuItem Header="Window">
<MenuItem IsCheckable="True" Header="ShowInTaskbar"
Expand Down
2 changes: 1 addition & 1 deletion samples/MetroDemo/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public partial class MainWindow

public MainWindow()
{
_viewModel = new MainWindowViewModel();
_viewModel = new MainWindowViewModel(DialogCoordinator.Instance);
DataContext = _viewModel;

InitializeComponent();
Expand Down
Loading