Skip to content

Instantly share code, notes, and snippets.

@tianvan
Last active September 12, 2024 06:50
Show Gist options
  • Select an option

  • Save tianvan/7c9422293ae52f72a682858101598277 to your computer and use it in GitHub Desktop.

Select an option

Save tianvan/7c9422293ae52f72a682858101598277 to your computer and use it in GitHub Desktop.
Prism combine with Material Design Toolkit Dialog
namespace Core.Services.Dialog
{
public class DialogHostRegionAdapter : RegionAdapterBase<DialogHost>
{
public DialogHostRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory)
{
}
protected override void Adapt(IRegion region, DialogHost regionTarget)
{
if (regionTarget == null)
{
throw new ArgumentNullException("regionTarget");
}
if (regionTarget.Content != null || BindingOperations.GetBinding(regionTarget, DialogHost.DialogContentProperty) != null)
{
throw new InvalidOperationException("DialogContent can not be set");
}
region.ActiveViews.CollectionChanged += (sender, e) => regionTarget.DialogContent = region.ActiveViews.FirstOrDefault();
region.Views.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add && !region.ActiveViews.Any())
{
region.Activate(e.NewItems[0]);
}
};
}
protected override IRegion CreateRegion() => new SingleActiveRegion();
}
}
namespace Core.Services.Dialog
{
public class DialogService : IDialogService
{
private readonly IUnityContainer _container;
private readonly IRegionManager _regionManager;
public DialogService(IUnityContainer container, IRegionManager regionManager)
{
_container = container;
_regionManager = regionManager;
}
public void Show(string name, dynamic parameters, System.Action<dynamic> callback)
{
IRegion region = _regionManager.Regions["DialogRegion"];
var view = _container.Resolve(typeof(object), name);
if (!(view is UIElement))
{
throw new ArgumentException("A dialog must be a UIElement");
}
var dialog = view as FrameworkElement;
if (!(dialog.DataContext is IDialogAware))
{
throw new ArgumentException("A dialog's ViewModel must implement IDialogAware interface");
}
var viewModel = dialog.DataContext as IDialogAware;
DialogHost dialogHost = FindChild<DialogHost>(Application.Current.MainWindow, default);
ConfigureEvents(dialogHost, viewModel, callback);
MvvmHelpers.ViewAndViewModelAction<IDialogAware>(viewModel, d => d.OnDialogOpened(parameters));
_ = region.Add(dialog);
region.Activate(dialog);
dialogHost.IsOpen = true;
}
private void ConfigureEvents(DialogHost dialogHost, IDialogAware viewModel, Action<dynamic> callback)
{
dynamic temp = default;
dialogHost.DialogOpened += DialogOpenedHandler;
dialogHost.DialogClosing += DialogClosedHandler;
void DialogOpenedHandler(object sender, RoutedEventArgs e)
{
dialogHost.DialogOpened -= DialogOpenedHandler;
viewModel.RequestClose += RequestCloseHandler;
}
void RequestCloseHandler(dynamic result)
{
temp = result;
dialogHost.IsOpen = false;
}
void DialogClosedHandler(object sender, RoutedEventArgs e)
{
dialogHost.DialogClosing -= DialogClosedHandler;
viewModel.RequestClose -= RequestCloseHandler;
viewModel.OnDialogClosed();
_ = callback?.Invoke(temp);
}
}
public void ShowDialog(string name, dynamic parameters, System.Action<dynamic> callback) => throw new System.NotImplementedException();
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
{
if (parent == null)
{
return default;
}
T foundChild = default;
var childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (var i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (!(child is T))
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null)
{
break;
}
}
else if (!string.IsNullOrEmpty(childName))
{
if (child is FrameworkElement frameworkElement && frameworkElement.Name == childName)
{
foundChild = (T)child;
break;
}
}
else
{
foundChild = (T)child;
break;
}
}
return foundChild;
}
}
}
<UserControl x:Class="Dialogs.ExitApplicationDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:properties="clr-namespace:Properties"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/Button.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Border CornerRadius="8"
Background="White">
<StackPanel>
<StackPanel Margin="24,16,24,28">
<TextBlock Text="{x:Static properties:Resources.ExitApplicationDialogHeader}"
Style="{DynamicResource MaterialDesignHeadlineTextBlock}" />
<TextBlock Margin="0,23,0,0"
Style="{DynamicResource MaterialDesignBody1TextBlock}"
Text="{x:Static properties:Resources.ExitApplicationDialogBody}"
TextWrapping="WrapWithOverflow" />
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="8">
<Button Content="{x:Static properties:Resources.Cancel}"
Margin="0,0,8,0"
Style="{DynamicResource MaterialDesignFlatButton}"
Command="{Binding CancelCommand}" />
<Button Content="{x:Static properties:Resources.Confirm}"
Style="{DynamicResource MaterialDesignFlatButton}"
Command="{Binding ConfirmCommand}" />
</StackPanel>
</StackPanel>
</Border>
</UserControl>
namespace Dialogs
{
/// <summary>
/// Interaction logic for ExitDialog.xaml
/// </summary>
public partial class ExitApplicationDialog : UserControl
{
public ExitApplicationDialog(ExitApplicationDialogViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
}
namespace Dialogs
{
public class ExitApplicationDialogViewModel : IDialogAware
{
private readonly IWorkspaceManger _workspaceManger;
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
private MetroWindow _metroWindow;
public ExitApplicationDialogViewModel(IWorkspaceManger workspaceManger, ISnackbarMessageQueue snackbarMessageQueue)
{
_workspaceManger = workspaceManger;
_snackbarMessageQueue = snackbarMessageQueue;
}
public event Action<dynamic> RequestClose;
public void OnDialogClosed()
{
// Method intentionally left empty.
}
public void OnDialogOpened(dynamic parameters)
{
_metroWindow = Application.Current.MainWindow as MetroWindow;
_metroWindow.IsCloseButtonEnabled = false;
}
private DelegateCommand _cancelCommand;
public DelegateCommand CancelCommand =>
_cancelCommand ?? (_cancelCommand = new DelegateCommand(ExecuteCancelCommand));
private void ExecuteCancelCommand()
{
RequestClose?.Invoke(default);
_metroWindow.IsCloseButtonEnabled = true;
}
private DelegateCommand _confirmCommand;
public DelegateCommand ConfirmCommand =>
_confirmCommand ?? (_confirmCommand = new DelegateCommand(ExecuteConfirmCommand));
private void ExecuteConfirmCommand()
{
foreach (IntegratedControl item in Application.Current.MainWindow.FindChildren<IntegratedControl>())
{
item.Save();
}
RequestClose?.Invoke(default);
Application.Current.Shutdown(0);
}
}
}
namespace Core.Services.Dialog
{
public interface IDialogAware
{
void OnDialogClosed();
void OnDialogOpened(dynamic parameters);
event Action<dynamic> RequestClose;
}
}
namespace Core.Services.Dialog
{
public interface IDialogService
{
void Show(string name, dynamic parameters, Action<dynamic> callback);
void ShowDialog(string name, dynamic parameters, Action<dynamic> callback);
}
}
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
<materialDesign:DialogHost prism:RegionManager.RegionName="DialogRegion" />
@AcidRaZor
Copy link
Copy Markdown

How do you call the dialog once all classes have been created and regionAdapter has been registered? RequestNavigate does nothing

@tianvan
Copy link
Copy Markdown
Author

tianvan commented Oct 8, 2020

How do you call the dialog once all classes have been created and regionAdapter has been registered? RequestNavigate does nothing

_dialogService.Show(nameof(ExitApplicationDialog));

@Honey-Fist
Copy link
Copy Markdown

what is MvvmHelpers?

@elusive
Copy link
Copy Markdown

elusive commented Sep 28, 2021

what is MvvmHelpers?

builtin helper class in Prism

@Andy1666
Copy link
Copy Markdown

Hey, i createt a PopupDialogServive using the IDialogAware from prism.

https://gist.github.com/Andy1666/03a5ccb98603aa7241e04f976382050b

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