Skip to content

Instantly share code, notes, and snippets.

@gofer
Last active April 4, 2022 15:05
Show Gist options
  • Save gofer/ca7e12d2a503d1bd27ce563481a3d5c3 to your computer and use it in GitHub Desktop.
Save gofer/ca7e12d2a503d1bd27ce563481a3d5c3 to your computer and use it in GitHub Desktop.
ModalWindowBase
<UserControl x:Class="Prism6Sample.Wpf.Common.Views.ModalWindowBase"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
xmlns:local="clr-namespace:Prism6Sample.Wpf.Common.Views"
Style="{DynamicResource ModalWindowBaseStyle}"
mc:Ignorable="d"
d:DesignHeight="720" d:DesignWidth="1280">
<UserControl.Resources>
<system:TimeSpan x:Key="FadeBeginTimespan">0:0:0.21</system:TimeSpan>
<Duration x:Key="FadeDuration">0:0:0.20</Duration>
<Style x:Key="CloseButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<ContentPresenter />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Content" Value="✕" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="#CFFFFFFF" />
<Setter Property="Opacity" Value="0.8" />
<Setter Property="FontSize" Value="32" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Margin" Value="0,20,20,0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Width" Value="40" />
<Setter Property="Height" Value="40" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="#FFFFFFFF" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ModalWindowBackgroundBorderStyle" TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding ModalVisibility.Value}"
Value="{x:Static Visibility.Visible}">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="{StaticResource FadeDuration}"
From="0"
To="0.667" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="{StaticResource FadeDuration}"
From="0.667"
To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="ModalWindowRegionGridVisiblityStyle" TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding ModalVisibility.Value}"
Value="{x:Static Visibility.Visible}">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="{StaticResource FadeDuration}"
From="0"
To="1" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="{StaticResource FadeDuration}"
From="1"
To="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="ModalWindowGridVisiblityStyle" TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding ModalVisibility.Value, UpdateSourceTrigger=PropertyChanged}"
Value="{x:Static Visibility.Visible}">
<DataTrigger.EnterActions>
<BeginStoryboard Name="VisiblityVisibleBeginStoryboard">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
BeginTime="0:0:0"
Duration="0">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="VisiblityVisibleBeginStoryboard" />
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding ModalVisibility.Value, UpdateSourceTrigger=PropertyChanged}"
Value="{x:Static Visibility.Collapsed}">
<DataTrigger.EnterActions>
<BeginStoryboard Name="VisiblityCollapsedBeginStoryboard">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
BeginTime="{StaticResource FadeBeginTimespan}"
Duration="0">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="VisiblityCollapsedBeginStoryboard" />
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding ModalVisibility.Value, UpdateSourceTrigger=PropertyChanged}"
Value="{x:Static Visibility.Hidden}">
<DataTrigger.EnterActions>
<BeginStoryboard Name="VisiblityHiddenBeginStoryboard">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
BeginTime="0:0:0"
Duration="0">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="VisiblityHiddenBeginStoryboard" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="ModalWindowBaseStyle" TargetType="{x:Type UserControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type UserControl}">
<Grid>
<ContentPresenter />
<Grid x:Name="ModalGrid" Style="{StaticResource ModalWindowGridVisiblityStyle}">
<Border Background="Black"
Style="{StaticResource ModalWindowBackgroundBorderStyle}" />
<Grid Style="{StaticResource ModalWindowRegionGridVisiblityStyle}">
<UserControl prism:RegionManager.RegionName="ModalWindowRegion"
prism:RegionManager.RegionManager="{Binding RegionManager}"/>
<Button Visibility="{Binding CloseButtonVisibility.Value}"
Style="{StaticResource CloseButtonStyle}"
Command="{Binding CloseCommand}" />
</Grid>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
</UserControl>
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows;
using DryIoc;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using Reactive.Bindings;
using Prism6Sample.Wpf.Common.Events;
using System.Windows.Controls;
using System.Threading.Tasks;
namespace Prism6Sample.Wpf.Common.ViewModels
{
public class ModalWindowBaseViewModel : BindableBase, IDisposable
{
private IContainer _Container = null;
private IEventAggregator _EventAggregator = null;
private IRegionManager _RegionManager = null;
public IRegionManager RegionManager
{
get
{
return _RegionManager;
}
}
public ReactiveProperty<Visibility> ModalVisibility { get; private set; }
= new ReactiveProperty<Visibility>(Visibility.Hidden);
public ReadOnlyReactiveProperty<bool> IsOpen { get; private set; }
public ReactiveProperty<bool> UseCloseButton { get; private set; }
= new ReactiveProperty<bool>(false);
public ReadOnlyReactiveProperty<Visibility> CloseButtonVisibility { get; private set; }
public ReactiveCommand CloseCommand { get; private set; }
= new ReactiveCommand();
private CompositeDisposable _CompositeDisposable = new CompositeDisposable();
public ModalWindowBaseViewModel(IContainer Container, IEventAggregator EventAggregator, IRegionManager RegionManager)
{
this._Container = Container;
this._EventAggregator = EventAggregator;
this._RegionManager = RegionManager;
_EventAggregator.GetEvent<ModalWindowOpenEvent>().Subscribe(() => {
ModalVisibility.Value = Visibility.Visible;
});
_EventAggregator.GetEvent<ModalWindowCloseEvent>().Subscribe(() => {
ModalVisibility.Value = Visibility.Collapsed;
});
_EventAggregator.GetEvent<ModalWindowToggleEvent>().Subscribe(() => {
switch (ModalVisibility.Value)
{
case Visibility.Visible:
_EventAggregator.GetEvent<ModalWindowCloseEvent>().Publish();
break;
case Visibility.Hidden:
ModalVisibility.Value = Visibility.Collapsed;
_EventAggregator.GetEvent<ModalWindowOpenEvent>().Publish();
break;
case Visibility.Collapsed:
_EventAggregator.GetEvent<ModalWindowOpenEvent>().Publish();
break;
}
});
IsOpen = ModalVisibility.Select(v => v == Visibility.Visible)
.ToReadOnlyReactiveProperty();
CloseButtonVisibility = UseCloseButton.Select(f => f ? Visibility.Visible : Visibility.Hidden)
.ToReadOnlyReactiveProperty();
CloseCommand.Subscribe(_ => {
_EventAggregator.GetEvent<ModalWindowCloseEvent>().Publish();
});
_CompositeDisposable.Add(ModalVisibility);
_CompositeDisposable.Add(CloseCommand);
}
public void Dispose()
{
_CompositeDisposable.Dispose();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment