Skip to content

Commit

Permalink
Refactor dialog controls to MVVM
Browse files Browse the repository at this point in the history
  • Loading branch information
Yoooi0 committed Sep 2, 2021
1 parent 443f5e6 commit 4d1c5f5
Show file tree
Hide file tree
Showing 16 changed files with 113 additions and 83 deletions.
7 changes: 6 additions & 1 deletion MultiFunPlayer/Bootstrapper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using MultiFunPlayer.Common;
using MultiFunPlayer.Common.Controls;
using MultiFunPlayer.Common.Converters;
using MultiFunPlayer.Common.Input;
using MultiFunPlayer.Common.Input.RawInput;
Expand Down Expand Up @@ -35,10 +36,14 @@ protected override void ConfigureIoC(IStyletIoCBuilder builder)

builder.Bind<IShortcutManager>().To<ShortcutManager>().InSingletonScope();
builder.Bind<IInputProcessor>().ToAllImplementations().InSingletonScope();

builder.Bind<DialogHelper>().To<DialogHelper>().InSingletonScope();
}

protected override void OnStart()
protected override void Configure()
{
_ = Container.Get<DialogHelper>();

SetupDevice();
SetupJson();
SetupLoging();
Expand Down
39 changes: 39 additions & 0 deletions MultiFunPlayer/Common/Controls/DialogHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using MaterialDesignThemes.Wpf;
using Stylet;
using System.Threading.Tasks;
using System.Windows;

namespace MultiFunPlayer.Common.Controls
{
public class DialogHelper
{
private static DialogHelper Instance { get; set; }
private IViewManager ViewManager { get; }

public DialogHelper(IViewManager viewManager)
{
Instance = this;
ViewManager = viewManager;
}

public static Task ShowOnUIThreadAsync(object model, string dialogName)
=> _ = Execute.OnUIThreadAsync(async () => await ShowAsync(model, dialogName));

public static async Task<object> ShowAsync(object model, string dialogName)
{
var view = Instance.ViewManager.CreateAndBindViewForModelIfNecessary(model);
var session = DialogHost.GetDialogSession(dialogName);
var sessionContext = (session?.Content as FrameworkElement)?.DataContext;
if (model.Equals(sessionContext))
return null;

if (DialogHost.IsDialogOpen(dialogName))
DialogHost.Close(dialogName);

(model as IScreenState)?.Activate();
var result = await DialogHost.Show(view, dialogName).ConfigureAwait(true);
(model as IScreenState)?.Deactivate();
return result;
}
}
}
18 changes: 0 additions & 18 deletions MultiFunPlayer/Common/Controls/ErrorMessageDialog.xaml.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Stylet;

namespace MultiFunPlayer.Common.Controls.ViewModels
{
public class ErrorMessageDialogViewModel : Screen
{
public string Message { get; }

public ErrorMessageDialogViewModel(string message) => Message = message;

public override bool Equals(object obj)
=> obj != null && GetType() == obj.GetType() && GetHashCode() == obj.GetHashCode();

public override int GetHashCode() => Message.GetHashCode();
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
using MaterialDesignThemes.Wpf;
using Stylet;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace MultiFunPlayer.Common.Controls
namespace MultiFunPlayer.Common.Controls.ViewModels
{
/// <summary>
/// Interaction logic for InformationMessageDialog.xaml
/// </summary>
public partial class InformationMessageDialog : UserControl
public class InformationMessageDialogViewModel : Screen
{
public string VersionText => $"v{Assembly.GetEntryAssembly().GetName().Version}";
public bool ShowCheckbox { get; }
public bool DontShowAgain { get; set; }

public InformationMessageDialog(bool showCheckbox)
public InformationMessageDialogViewModel(bool showCheckbox)
{
ShowCheckbox = showCheckbox;

InitializeComponent();
}

public void OnDismiss()
Expand All @@ -35,5 +30,10 @@ public void OnNavigate(object sender, RequestNavigateEventArgs e)
});
e.Handled = true;
}

public override bool Equals(object obj)
=> obj != null && GetType() == obj.GetType();

public override int GetHashCode() => VersionText.GetHashCode();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<UserControl x:Class="MultiFunPlayer.Common.Controls.ErrorMessageDialog"
<UserControl x:Class="MultiFunPlayer.Common.Controls.Views.ErrorMessageDialogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand All @@ -11,13 +11,15 @@
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="{Binding Message, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
Margin="0 0 0 20"
TextWrapping="Wrap"
MaxWidth="800"/>
<TextBox Grid.Row="0"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
Text="{Binding Message, Mode=OneWay}"
FontFamily="Consolas"
Margin="0 0 0 20"
TextWrapping="Wrap"
MaxWidth="800"/>
<Button Grid.Row="1"
Content="OK"
Content="Dismiss"
IsDefault="True" Style="{DynamicResource MaterialDesignFlatLightBgButton}"
HorizontalAlignment="Center"
Command="{x:Static material:DialogHost.CloseDialogCommand}"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<UserControl x:Class="MultiFunPlayer.Common.Controls.InformationMessageDialog"
<UserControl x:Class="MultiFunPlayer.Common.Controls.Views.InformationMessageDialogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
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:local="clr-namespace:MultiFunPlayer.Common.Controls"
xmlns:local="clr-namespace:MultiFunPlayer.Common.Controls.Views"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="400">
<Grid Width="450" Margin="20">
Expand All @@ -18,7 +18,7 @@
<Grid HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock TextAlignment="Center"
Text="{Binding VersionText, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
Text="{Binding VersionText}"
Margin="0 0 5 0"/>
<TextBlock TextAlignment="Center">by Yoooi</TextBlock>
</StackPanel>
Expand All @@ -33,7 +33,6 @@
Check my
<material:PackIcon Kind="Github" Margin="0 -3 0 -3"/>
<Hyperlink NavigateUri="http://github.com/Yoooi0"
s:View.ActionTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
RequestNavigate="{s:Action OnNavigate}">
GitHub
</Hyperlink>
Expand All @@ -48,7 +47,6 @@
<material:PackIcon Kind="Patreon"
Margin="0 -3 0 -3"/>
<Hyperlink NavigateUri="https://patreon.com/Yoooi"
s:View.ActionTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
RequestNavigate="{s:Action OnNavigate}">
Patreon
</Hyperlink>
Expand All @@ -66,10 +64,9 @@
<Button Content="Dismiss"
IsDefault="True" Style="{DynamicResource MaterialDesignFlatLightBgButton}"
HorizontalAlignment="Center"
s:View.ActionTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
Command="{s:Action OnDismiss}"/>
<CheckBox IsChecked="{Binding DontShowAgain, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
Visibility="{Binding ShowCheckbox, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Converter={StaticResource BooleanToVisibilityConverter}}"
<CheckBox IsChecked="{Binding DontShowAgain}"
Visibility="{Binding ShowCheckbox, Converter={StaticResource BooleanToVisibilityConverter}}"
Margin="0 10 0 0"
HorizontalAlignment="Center"
Content="Don't show again"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using MaterialDesignThemes.Wpf;
using MultiFunPlayer.Common;
using MultiFunPlayer.Common.Controls;
using MultiFunPlayer.Common.Controls.ViewModels;
using MultiFunPlayer.Common.Input;
using MultiFunPlayer.Common.Messages;
using Newtonsoft.Json;
Expand Down Expand Up @@ -163,7 +164,7 @@ void OnDeviceAdded(ButtplugClientDevice device)
if (client.Connected)
await client.DisconnectAsync();

_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"Error when connecting to server:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"Error when connecting to server:\n\n{e}"), "RootDialog"));
return;
}

Expand Down Expand Up @@ -227,7 +228,7 @@ bool IsDirty(DeviceAxis axis)
catch (Exception e)
{
Logger.Error(e, $"{Name} failed with exception");
_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"{Name} failed with exception:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"{Name} failed with exception:\n\n{e}"), "RootDialog"));
}

if (client.Connected)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using MaterialDesignThemes.Wpf;
using MultiFunPlayer.Common;
using MultiFunPlayer.Common.Controls;
using MultiFunPlayer.Common.Controls.ViewModels;
using MultiFunPlayer.Common.Input;
using MultiFunPlayer.Common.Messages;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -63,7 +64,7 @@ private void RunTcp(CancellationToken token)
catch (Exception e)
{
Logger.Warn(e, "Error when connecting to server");
_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"Error when connecting to server:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"Error when connecting to server:\n\n{e}"), "RootDialog"));
return;
}

Expand All @@ -88,7 +89,7 @@ private void RunTcp(CancellationToken token)
catch (Exception e)
{
Logger.Error(e, "Unhandled error");
_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"Unhandled error:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"Unhandled error:\n\n{e}"), "RootDialog"));
}
}

Expand All @@ -105,7 +106,7 @@ private void RunUdp(CancellationToken token)
catch (Exception e)
{
Logger.Warn(e, "Error when connecting to server");
_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"Error when connecting to server:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"Error when connecting to server:\n\n{e}"), "RootDialog"));
return;
}

Expand Down Expand Up @@ -133,7 +134,7 @@ private void RunUdp(CancellationToken token)
catch (Exception e)
{
Logger.Error(e, $"{Name} failed with exception");
_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"{Name} failed with exception:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"{Name} failed with exception:\n\n{e}"), "RootDialog"));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using MaterialDesignThemes.Wpf;
using MultiFunPlayer.Common;
using MultiFunPlayer.Common.Controls;
using MultiFunPlayer.Common.Controls.ViewModels;
using MultiFunPlayer.Common.Input;
using MultiFunPlayer.Common.Messages;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -50,7 +51,7 @@ protected override void Run(CancellationToken token)
if (client?.IsConnected == true)
client.Close();

_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"Error when opening pipe:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"Error when opening pipe:\n\n{e}"), "RootDialog"));
return;
}

Expand All @@ -76,7 +77,7 @@ protected override void Run(CancellationToken token)
catch (Exception e)
{
Logger.Error(e, $"{Name} failed with exception");
_ = Execute.OnUIThreadAsync(() => _ = DialogHost.Show(new ErrorMessageDialog($"{Name} failed with exception:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"{Name} failed with exception:\n\n{e}"), "RootDialog"));
}

if (client?.IsConnected == true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using MaterialDesignThemes.Wpf;
using MultiFunPlayer.Common;
using MultiFunPlayer.Common.Controls;
using MultiFunPlayer.Common.Controls.ViewModels;
using MultiFunPlayer.Common.Input;
using MultiFunPlayer.Common.Messages;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -93,7 +94,7 @@ protected override void Run(CancellationToken token)

_ = Execute.OnUIThreadAsync(async () =>
{
_ = DialogHost.Show(new ErrorMessageDialog($"Error when opening serial port:\n\n{e}"));
_ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"Error when opening serial port:\n\n{e}"), "RootDialog");
await RefreshPorts().ConfigureAwait(true);
});

Expand Down Expand Up @@ -127,7 +128,7 @@ protected override void Run(CancellationToken token)
Logger.Error(e, $"{Name} failed with exception");
_ = Execute.OnUIThreadAsync(async () =>
{
_ = DialogHost.Show(new ErrorMessageDialog($"{Name} failed with exception:\n\n{e}"));
_ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"{Name} failed with exception:\n\n{e}"), "RootDialog");
await RefreshPorts().ConfigureAwait(true);
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using MaterialDesignThemes.Wpf;
using MultiFunPlayer.Common;
using MultiFunPlayer.Common.Controls;
using MultiFunPlayer.Common.Controls.ViewModels;
using MultiFunPlayer.Common.Input;
using MultiFunPlayer.Common.Messages;
using Newtonsoft.Json;
Expand Down Expand Up @@ -139,7 +140,7 @@ protected override async Task RunAsync(CancellationToken token)
catch (Exception e)
{
Logger.Error(e, $"{Name} failed with exception");
_ = Execute.OnUIThreadAsync(() => DialogHost.Show(new ErrorMessageDialog($"{Name} failed with exception:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => _ = DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"{Name} failed with exception:\n\n{e}"), "RootDialog"));
}

_eventAggregator.Publish(new VideoFileChangedMessage(null));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using MaterialDesignThemes.Wpf;
using MultiFunPlayer.Common;
using MultiFunPlayer.Common.Controls;
using MultiFunPlayer.Common.Controls.ViewModels;
using MultiFunPlayer.Common.Input;
using MultiFunPlayer.Common.Messages;
using Newtonsoft.Json;
Expand Down Expand Up @@ -139,7 +140,7 @@ protected override async Task RunAsync(CancellationToken token)
catch (Exception e)
{
Logger.Error(e, $"{Name} failed with exception");
_ = Execute.OnUIThreadAsync(() => DialogHost.Show(new ErrorMessageDialog($"{Name} failed with exception:\n\n{e}")));
_ = Execute.OnUIThreadAsync(() => DialogHelper.ShowOnUIThreadAsync(new ErrorMessageDialogViewModel($"{Name} failed with exception:\n\n{e}"), "RootDialog"));
}

_eventAggregator.Publish(new VideoFileChangedMessage(null));
Expand Down
Loading

0 comments on commit 4d1c5f5

Please sign in to comment.