Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ButchersBoy/4a7272f3ac104c5b1a54 to your computer and use it in GitHub Desktop.

Select an option

Save ButchersBoy/4a7272f3ac104c5b1a54 to your computer and use it in GitHub Desktop.
Demo of how to call MahApps dialogs from a view model, without knowledge of MetroWindow. MVVM framework agnostic.
public partial class Mah : UserControl
{
public Mah()
{
DataContext = new MahViewModel();
InitializeComponent();
}
}
public class MahViewModel
{
private readonly ICommand _launchDialog;
public MahViewModel()
{
_launchDialog = new AnotherCommandImplementation(_ => ShowDialog());
}
private void ShowDialog()
{
DialogCoordinator.ShowDialog(this);
}
public ICommand LaunchDialog
{
get { return _launchDialog; }
}
}
public static class DialogCoordinator
{
public static Task<string> ShowDialog(object context)
{
if (context == null) throw new ArgumentNullException(nameof(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.ShowInputAsync("From a VM", "This dialog was shown from a VM, without knoweldge of Window");
}
}
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)
{
//TODO tidy up old val?
_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(nameof(context));
return _contextRegistrationIndex.ContainsKey(context);
}
internal static DependencyObject GetAssociation(object context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
return _contextRegistrationIndex[context];
}
}
<UserControl x:Class="MahMaterialDragablzMashUp.Mah"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:mahMaterialDragablzMashUp="clr-namespace:MahMaterialDragablzMashUp"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
mahMaterialDragablzMashUp:DialogParticipation.Register="{Binding RelativeSource={RelativeSource Self}, Path=DataContext}"
>
</UserControl>
@dasjestyr
Copy link

How does this actually get called from a metro window? As written, this will throw an exception since this is inside of a user control, not a metro window

@mbalous
Copy link

mbalous commented Jun 11, 2018

@dasjestyr Make sure the windows inherits from type MetroWindow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment