Custom print dialog and better message registrations

This commit is contained in:
Burak Kaan Köse
2025-10-21 01:27:29 +02:00
parent 4191b7314f
commit 057edb5488
27 changed files with 656 additions and 760 deletions
+14
View File
@@ -50,4 +50,18 @@ public sealed partial class AppShell : AppShellAbstract,
private void AppBarBackButtonClicked(Core.UWP.Controls.WinoAppTitleBar sender, RoutedEventArgs args) private void AppBarBackButtonClicked(Core.UWP.Controls.WinoAppTitleBar sender, RoutedEventArgs args)
=> ViewModel.NavigationService.GoBack(); => ViewModel.NavigationService.GoBack();
protected override void RegisterRecipients()
{
base.RegisterRecipients();
WeakReferenceMessenger.Default.Register<CalendarDisplayTypeChangedMessage>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
WeakReferenceMessenger.Default.Unregister<CalendarDisplayTypeChangedMessage>(this);
}
} }
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.Accounts;
using Wino.Core.Domain.Models.Common; using Wino.Core.Domain.Models.Common;
using Wino.Core.Domain.Models.Printing;
namespace Wino.Core.Domain.Interfaces; namespace Wino.Core.Domain.Interfaces;
@@ -28,4 +29,5 @@ public interface IDialogServiceBase
IAccountCreationDialog GetAccountCreationDialog(AccountCreationDialogResult accountCreationDialogResult); IAccountCreationDialog GetAccountCreationDialog(AccountCreationDialogResult accountCreationDialogResult);
Task<List<SharedFile>> PickFilesAsync(params object[] typeFilters); Task<List<SharedFile>> PickFilesAsync(params object[] typeFilters);
Task<string> PickFilePathAsync(string saveFileName); Task<string> PickFilePathAsync(string saveFileName);
Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(WebView2PrintSettingsModel initialSettings = null);
} }
@@ -8,7 +8,7 @@ namespace Wino.Core.Domain.Models.MailItem;
/// </summary> /// </summary>
public class MailDragPackage public class MailDragPackage
{ {
public MailDragPackage(IEnumerable<MailCopy> draggingMails) public MailDragPackage(IEnumerable<object> draggingMails)
{ {
DraggingMails = draggingMails; DraggingMails = draggingMails;
} }
@@ -21,5 +21,5 @@ public class MailDragPackage
]; ];
} }
public IEnumerable<MailCopy> DraggingMails { get; set; } public IEnumerable<object> DraggingMails { get; set; }
} }
@@ -1,4 +1,5 @@
using System.ComponentModel; using System;
using CommunityToolkit.Mvvm.ComponentModel;
using Wino.Core.Domain.Enums; using Wino.Core.Domain.Enums;
namespace Wino.Core.Domain.Models.Printing; namespace Wino.Core.Domain.Models.Printing;
@@ -6,339 +7,131 @@ namespace Wino.Core.Domain.Models.Printing;
/// <summary> /// <summary>
/// Wrapper model for CoreWebView2PrintSettings that provides bindable properties for UI controls. /// Wrapper model for CoreWebView2PrintSettings that provides bindable properties for UI controls.
/// </summary> /// </summary>
public class WebView2PrintSettingsModel : INotifyPropertyChanged public partial class WebView2PrintSettingsModel : ObservableObject
{ {
private string _printerName = string.Empty; [ObservableProperty]
private PrintOrientation _orientation = PrintOrientation.Portrait; public partial string PrinterName { get; set; } = string.Empty;
private PrintColorMode _colorMode = PrintColorMode.Color;
private PrintCollation _collation = PrintCollation.Default;
private PrintDuplex _duplex = PrintDuplex.Default;
private PrintMediaSize _mediaSize = PrintMediaSize.Default;
private int _copies = 1;
private double _marginTop = 1.0;
private double _marginBottom = 1.0;
private double _marginLeft = 1.0;
private double _marginRight = 1.0;
private bool _shouldPrintBackgrounds = false;
private bool _shouldPrintSelectionOnly = false;
private bool _shouldPrintHeaderAndFooter = true;
private string _headerTitle = string.Empty;
private string _footerUri = string.Empty;
private double _scaleFactor = 1.0;
private int _pagesPerSide = 1;
private string _pageRanges = string.Empty;
public event PropertyChangedEventHandler PropertyChanged; [ObservableProperty]
public partial PrintOrientation Orientation { get; set; } = PrintOrientation.Portrait;
[ObservableProperty]
public partial PrintColorMode ColorMode { get; set; } = PrintColorMode.Color;
[ObservableProperty]
public partial PrintCollation Collation { get; set; } = PrintCollation.Default;
[ObservableProperty]
public partial PrintDuplex Duplex { get; set; } = PrintDuplex.Default;
[ObservableProperty]
public partial PrintMediaSize MediaSize { get; set; } = PrintMediaSize.Default;
[ObservableProperty]
public partial int Copies { get; set; } = 1;
[ObservableProperty]
public partial double MarginTop { get; set; } = 1.0;
[ObservableProperty]
public partial double MarginBottom { get; set; } = 1.0;
[ObservableProperty]
public partial double MarginLeft { get; set; } = 1.0;
[ObservableProperty]
public partial double MarginRight { get; set; } = 1.0;
[ObservableProperty]
public partial bool ShouldPrintBackgrounds { get; set; } = false;
[ObservableProperty]
public partial bool ShouldPrintSelectionOnly { get; set; } = false;
[ObservableProperty]
public partial bool ShouldPrintHeaderAndFooter { get; set; } = true;
[ObservableProperty]
public partial string HeaderTitle { get; set; } = string.Empty;
[ObservableProperty]
public partial string FooterUri { get; set; } = string.Empty;
[ObservableProperty]
public partial double ScaleFactor { get; set; } = 1.0;
[ObservableProperty]
public partial int PagesPerSide { get; set; } = 1;
[ObservableProperty]
public partial string PageRanges { get; set; } = string.Empty;
/// <summary> /// <summary>
/// Name of the printer to use for printing. /// Partial method for validation when Copies property changes.
/// </summary> /// </summary>
public string PrinterName partial void OnCopiesChanged(int value)
{ {
get => _printerName; if (value <= 0)
set
{ {
if (_printerName != value) Copies = 1; // Reset to minimum valid value
{
_printerName = value;
OnPropertyChanged(nameof(PrinterName));
}
} }
} }
/// <summary> /// <summary>
/// Orientation of the printed document. /// Partial method for validation when ScaleFactor property changes.
/// </summary> /// </summary>
public PrintOrientation Orientation partial void OnScaleFactorChanged(double value)
{ {
get => _orientation; if (value < 0.1 || value > 2.0)
set
{ {
if (_orientation != value) ScaleFactor = Math.Clamp(value, 0.1, 2.0);
{
_orientation = value;
OnPropertyChanged(nameof(Orientation));
}
} }
} }
/// <summary> /// <summary>
/// Color mode for printing. /// Partial method for validation when PagesPerSide property changes.
/// </summary> /// </summary>
public PrintColorMode ColorMode partial void OnPagesPerSideChanged(int value)
{ {
get => _colorMode; var validValues = new[] { 1, 2, 4, 6, 9, 16 };
set if (System.Array.IndexOf(validValues, value) < 0)
{ {
if (_colorMode != value) PagesPerSide = 1; // Reset to default valid value
{
_colorMode = value;
OnPropertyChanged(nameof(ColorMode));
}
} }
} }
/// <summary> /// <summary>
/// Collation setting for multiple copies. /// Partial method for validation when margin properties change.
/// </summary> /// </summary>
public PrintCollation Collation partial void OnMarginTopChanged(double value)
{ {
get => _collation; if (value < 0)
set
{ {
if (_collation != value) MarginTop = 0;
{
_collation = value;
OnPropertyChanged(nameof(Collation));
}
} }
} }
/// <summary> partial void OnMarginBottomChanged(double value)
/// Duplex printing mode.
/// </summary>
public PrintDuplex Duplex
{ {
get => _duplex; if (value < 0)
set
{ {
if (_duplex != value) MarginBottom = 0;
{
_duplex = value;
OnPropertyChanged(nameof(Duplex));
}
} }
} }
/// <summary> partial void OnMarginLeftChanged(double value)
/// Media size for printing.
/// </summary>
public PrintMediaSize MediaSize
{ {
get => _mediaSize; if (value < 0)
set
{ {
if (_mediaSize != value) MarginLeft = 0;
{
_mediaSize = value;
OnPropertyChanged(nameof(MediaSize));
}
} }
} }
/// <summary> partial void OnMarginRightChanged(double value)
/// Number of copies to print.
/// </summary>
public int Copies
{ {
get => _copies; if (value < 0)
set
{ {
if (_copies != value && value > 0) MarginRight = 0;
{
_copies = value;
OnPropertyChanged(nameof(Copies));
}
} }
} }
/// <summary>
/// Top margin in inches.
/// </summary>
public double MarginTop
{
get => _marginTop;
set
{
if (_marginTop != value && value >= 0)
{
_marginTop = value;
OnPropertyChanged(nameof(MarginTop));
}
}
}
/// <summary>
/// Bottom margin in inches.
/// </summary>
public double MarginBottom
{
get => _marginBottom;
set
{
if (_marginBottom != value && value >= 0)
{
_marginBottom = value;
OnPropertyChanged(nameof(MarginBottom));
}
}
}
/// <summary>
/// Left margin in inches.
/// </summary>
public double MarginLeft
{
get => _marginLeft;
set
{
if (_marginLeft != value && value >= 0)
{
_marginLeft = value;
OnPropertyChanged(nameof(MarginLeft));
}
}
}
/// <summary>
/// Right margin in inches.
/// </summary>
public double MarginRight
{
get => _marginRight;
set
{
if (_marginRight != value && value >= 0)
{
_marginRight = value;
OnPropertyChanged(nameof(MarginRight));
}
}
}
/// <summary>
/// Whether to print background colors and images.
/// </summary>
public bool ShouldPrintBackgrounds
{
get => _shouldPrintBackgrounds;
set
{
if (_shouldPrintBackgrounds != value)
{
_shouldPrintBackgrounds = value;
OnPropertyChanged(nameof(ShouldPrintBackgrounds));
}
}
}
/// <summary>
/// Whether to print only the selected content.
/// </summary>
public bool ShouldPrintSelectionOnly
{
get => _shouldPrintSelectionOnly;
set
{
if (_shouldPrintSelectionOnly != value)
{
_shouldPrintSelectionOnly = value;
OnPropertyChanged(nameof(ShouldPrintSelectionOnly));
}
}
}
/// <summary>
/// Whether to print header and footer.
/// </summary>
public bool ShouldPrintHeaderAndFooter
{
get => _shouldPrintHeaderAndFooter;
set
{
if (_shouldPrintHeaderAndFooter != value)
{
_shouldPrintHeaderAndFooter = value;
OnPropertyChanged(nameof(ShouldPrintHeaderAndFooter));
}
}
}
/// <summary>
/// Title to display in the header.
/// </summary>
public string HeaderTitle
{
get => _headerTitle;
set
{
if (_headerTitle != value)
{
_headerTitle = value ?? string.Empty;
OnPropertyChanged(nameof(HeaderTitle));
}
}
}
/// <summary>
/// URI to display in the footer.
/// </summary>
public string FooterUri
{
get => _footerUri;
set
{
if (_footerUri != value)
{
_footerUri = value ?? string.Empty;
OnPropertyChanged(nameof(FooterUri));
}
}
}
/// <summary>
/// Scale factor for printing (0.1 to 2.0).
/// </summary>
public double ScaleFactor
{
get => _scaleFactor;
set
{
if (_scaleFactor != value && value >= 0.1 && value <= 2.0)
{
_scaleFactor = value;
OnPropertyChanged(nameof(ScaleFactor));
}
}
}
/// <summary>
/// Number of pages to print per sheet (1, 2, 4, 6, 9, 16).
/// </summary>
public int PagesPerSide
{
get => _pagesPerSide;
set
{
var validValues = new[] { 1, 2, 4, 6, 9, 16 };
if (_pagesPerSide != value && System.Array.IndexOf(validValues, value) >= 0)
{
_pagesPerSide = value;
OnPropertyChanged(nameof(PagesPerSide));
}
}
}
/// <summary>
/// Page ranges to print (e.g., "1-3,5,7-9").
/// </summary>
public string PageRanges
{
get => _pageRanges;
set
{
if (_pageRanges != value)
{
_pageRanges = value ?? string.Empty;
OnPropertyChanged(nameof(PageRanges));
}
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
@@ -9,4 +9,18 @@ public class CalendarBaseViewModel : CoreBaseViewModel, IRecipient<CalendarItemA
public void Receive(CalendarItemAdded message) => OnCalendarItemAdded(message.CalendarItem); public void Receive(CalendarItemAdded message) => OnCalendarItemAdded(message.CalendarItem);
protected virtual void OnCalendarItemAdded(CalendarItem calendarItem) { } protected virtual void OnCalendarItemAdded(CalendarItem calendarItem) { }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
Messenger.Register<CalendarItemAdded>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
Messenger.Unregister<CalendarItemAdded>(this);
}
} }
+18 -2
View File
@@ -33,9 +33,15 @@ public class CoreBaseViewModel : ObservableRecipient,
} }
} }
public virtual void OnNavigatedTo(NavigationMode mode, object parameters) { IsActive = true; } public virtual void OnNavigatedTo(NavigationMode mode, object parameters)
{
RegisterRecipients();
}
public virtual void OnNavigatedFrom(NavigationMode mode, object parameters) { IsActive = false; } public virtual void OnNavigatedFrom(NavigationMode mode, object parameters)
{
UnregisterRecipients();
}
public virtual void OnPageLoaded() { } public virtual void OnPageLoaded() { }
@@ -44,6 +50,16 @@ public class CoreBaseViewModel : ObservableRecipient,
protected virtual void OnDispatcherAssigned() { } protected virtual void OnDispatcherAssigned() { }
/// <summary>
/// Register message recipients for this view model. Override to register specific message types.
/// </summary>
protected virtual void RegisterRecipients() { }
/// <summary>
/// Unregister message recipients for this view model. Override to unregister specific message types.
/// </summary>
protected virtual void UnregisterRecipients() { }
protected virtual void OnAccountCreated(MailAccount createdAccount) { } protected virtual void OnAccountCreated(MailAccount createdAccount) { }
protected virtual void OnAccountRemoved(MailAccount removedAccount) { } protected virtual void OnAccountRemoved(MailAccount removedAccount) { }
protected virtual void OnAccountUpdated(MailAccount updatedAccount) { } protected virtual void OnAccountUpdated(MailAccount updatedAccount) { }
+14 -7
View File
@@ -1,6 +1,5 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
@@ -27,6 +26,16 @@ public partial class BasePage : Page, IRecipient<LanguageChanged>
} }
public virtual void OnLanguageChanged() { } public virtual void OnLanguageChanged() { }
/// <summary>
/// Register message recipients for this page. Override to register specific message types.
/// </summary>
protected virtual void RegisterRecipients() { }
/// <summary>
/// Unregister message recipients for this page. Override to unregister specific message types.
/// </summary>
protected virtual void UnregisterRecipients() { }
} }
public abstract class BasePage<T> : BasePage where T : CoreBaseViewModel public abstract class BasePage<T> : BasePage where T : CoreBaseViewModel
@@ -49,10 +58,7 @@ public abstract class BasePage<T> : BasePage where T : CoreBaseViewModel
private void PageLoaded(object sender, RoutedEventArgs e) => ViewModel.OnPageLoaded(); private void PageLoaded(object sender, RoutedEventArgs e) => ViewModel.OnPageLoaded();
~BasePage() ~BasePage() { Debug.WriteLine($"Disposed {GetType().Name}"); }
{
Debug.WriteLine($"Disposed {GetType().Name}");
}
protected override void OnNavigatedTo(NavigationEventArgs e) protected override void OnNavigatedTo(NavigationEventArgs e)
{ {
@@ -61,8 +67,8 @@ public abstract class BasePage<T> : BasePage where T : CoreBaseViewModel
var mode = GetNavigationMode(e.NavigationMode); var mode = GetNavigationMode(e.NavigationMode);
var parameter = e.Parameter; var parameter = e.Parameter;
WeakReferenceMessenger.Default.UnregisterAll(this);
WeakReferenceMessenger.Default.Register<LanguageChanged>(this); WeakReferenceMessenger.Default.Register<LanguageChanged>(this);
RegisterRecipients();
ViewModel.OnNavigatedTo(mode, parameter); ViewModel.OnNavigatedTo(mode, parameter);
} }
@@ -74,7 +80,8 @@ public abstract class BasePage<T> : BasePage where T : CoreBaseViewModel
var mode = GetNavigationMode(e.NavigationMode); var mode = GetNavigationMode(e.NavigationMode);
var parameter = e.Parameter; var parameter = e.Parameter;
WeakReferenceMessenger.Default.UnregisterAll(this); WeakReferenceMessenger.Default.Unregister<LanguageChanged>(this);
UnregisterRecipients();
ViewModel.OnNavigatedFrom(mode, parameter); ViewModel.OnNavigatedFrom(mode, parameter);
+47 -213
View File
@@ -1,220 +1,54 @@
<ContentDialog x:Class="Wino.Core.WinUI.Dialogs.PrintDialog" <ContentDialog
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:Class="Wino.Core.WinUI.Dialogs.PrintDialog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 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:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Print Settings" xmlns:printing="using:Wino.Core.Domain.Models.Printing"
PrimaryButtonText="Print" Title="Print Settings"
SecondaryButtonText="Cancel" MinWidth="400"
DefaultButton="Primary" MinHeight="300"
MinWidth="600" DefaultButton="Primary"
MinHeight="500" Loaded="PrintDialog_Loaded"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick" PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick"> PrimaryButtonText="Print"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick"
SecondaryButtonText="Cancel"
Style="{StaticResource WinoDialogStyle}"
mc:Ignorable="d">
<ScrollViewer> <StackPanel Margin="20" Spacing="16">
<StackPanel Spacing="16" Margin="20">
<!-- Printer Selection --> <!-- Printer Selection -->
<StackPanel Spacing="8"> <ComboBox
<TextBlock Text="Printer" FontWeight="SemiBold" /> x:Name="PrinterComboBox"
<ComboBox x:Name="PrinterComboBox" HorizontalAlignment="Stretch"
ItemsSource="{x:Bind ViewModel.AvailablePrinters, Mode=OneWay}" Header="Printer"
SelectedItem="{x:Bind ViewModel.PrintSettings.PrinterName, Mode=TwoWay}" SelectedItem="{x:Bind PrintSettings.PrinterName, Mode=TwoWay}"
Header="Select Printer" SelectionChanged="PrinterComboBox_SelectionChanged" />
HorizontalAlignment="Stretch" />
</StackPanel>
<!-- Print Options Grid --> <!-- Copies -->
<Grid> <NumberBox
<Grid.ColumnDefinitions> Header="Copies"
<ColumnDefinition Width="*" /> Maximum="999"
<ColumnDefinition Width="20" /> Minimum="1"
<ColumnDefinition Width="*" /> SpinButtonPlacementMode="Inline"
</Grid.ColumnDefinitions> Value="{x:Bind PrintSettings.Copies, Mode=TwoWay}" />
<!-- Left Column --> <!-- Orientation -->
<StackPanel Grid.Column="0" Spacing="16"> <RadioButtons
x:Name="OrientationRadioButtons"
<!-- Copies --> Header="Orientation"
<StackPanel Spacing="8"> SelectionChanged="OrientationRadio_SelectionChanged">
<TextBlock Text="Copies" FontWeight="SemiBold" /> <RadioButton Content="Portrait" />
<NumberBox Value="{x:Bind ViewModel.PrintSettings.Copies, Mode=TwoWay}" <RadioButton Content="Landscape" />
Minimum="1" Maximum="999" </RadioButtons>
SpinButtonPlacementMode="Inline" />
</StackPanel>
<!-- Orientation -->
<StackPanel Spacing="8">
<TextBlock Text="Orientation" FontWeight="SemiBold" />
<RadioButtons SelectedIndex="{x:Bind ViewModel.OrientationIndex, Mode=TwoWay}">
<RadioButton Content="Portrait" />
<RadioButton Content="Landscape" />
</RadioButtons>
</StackPanel>
<!-- Color Mode -->
<StackPanel Spacing="8">
<TextBlock Text="Color" FontWeight="SemiBold" />
<RadioButtons SelectedIndex="{x:Bind ViewModel.ColorModeIndex, Mode=TwoWay}">
<RadioButton Content="Default" />
<RadioButton Content="Color" />
<RadioButton Content="Grayscale" />
</RadioButtons>
</StackPanel>
<!-- Media Size -->
<StackPanel Spacing="8">
<TextBlock Text="Paper Size" FontWeight="SemiBold" />
<ComboBox SelectedIndex="{x:Bind ViewModel.MediaSizeIndex, Mode=TwoWay}"
HorizontalAlignment="Stretch">
<ComboBoxItem Content="Default" />
<ComboBoxItem Content="Letter (8.5 x 11 in)" />
<ComboBoxItem Content="Legal (8.5 x 14 in)" />
<ComboBoxItem Content="A4 (210 x 297 mm)" />
<ComboBoxItem Content="A3 (297 x 420 mm)" />
<ComboBoxItem Content="A5 (148 x 210 mm)" />
<ComboBoxItem Content="Tabloid (11 x 17 in)" />
<ComboBoxItem Content="Executive (7.25 x 10.5 in)" />
<ComboBoxItem Content="B4 (250 x 353 mm)" />
<ComboBoxItem Content="B5 (176 x 250 mm)" />
</ComboBox>
</StackPanel>
</StackPanel>
<!-- Right Column -->
<StackPanel Grid.Column="2" Spacing="16">
<!-- Duplex -->
<StackPanel Spacing="8">
<TextBlock Text="Duplex" FontWeight="SemiBold" />
<RadioButtons SelectedIndex="{x:Bind ViewModel.DuplexIndex, Mode=TwoWay}">
<RadioButton Content="Default" />
<RadioButton Content="Single-sided" />
<RadioButton Content="Double-sided (Short Edge)" />
<RadioButton Content="Double-sided (Long Edge)" />
</RadioButtons>
</StackPanel>
<!-- Collation -->
<StackPanel Spacing="8">
<TextBlock Text="Collation" FontWeight="SemiBold" />
<RadioButtons SelectedIndex="{x:Bind ViewModel.CollationIndex, Mode=TwoWay}">
<RadioButton Content="Default" />
<RadioButton Content="Collated" />
<RadioButton Content="Uncollated" />
</RadioButtons>
</StackPanel>
<!-- Pages Per Side -->
<StackPanel Spacing="8">
<TextBlock Text="Pages Per Side" FontWeight="SemiBold" />
<ComboBox SelectedIndex="{x:Bind ViewModel.PagesPerSideIndex, Mode=TwoWay}"
HorizontalAlignment="Stretch">
<ComboBoxItem Content="1" />
<ComboBoxItem Content="2" />
<ComboBoxItem Content="4" />
<ComboBoxItem Content="6" />
<ComboBoxItem Content="9" />
<ComboBoxItem Content="16" />
</ComboBox>
</StackPanel>
</StackPanel>
</Grid>
<!-- Page Range -->
<StackPanel Spacing="8">
<TextBlock Text="Page Range" FontWeight="SemiBold" />
<RadioButtons SelectedIndex="{x:Bind ViewModel.PageRangeOptionIndex, Mode=TwoWay}">
<RadioButton Content="All pages" />
<RadioButton Content="Custom range" />
</RadioButtons>
<TextBox x:Name="PageRangeTextBox"
Text="{x:Bind ViewModel.PrintSettings.PageRanges, Mode=TwoWay}"
PlaceholderText="e.g., 1-3,5,7-9"
IsEnabled="{x:Bind ViewModel.IsCustomPageRange, Mode=OneWay}"
Margin="0,8,0,0" />
</StackPanel>
<!-- Scale Factor -->
<StackPanel Spacing="8">
<TextBlock Text="Scale" FontWeight="SemiBold" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<Slider x:Name="ScaleSlider"
Value="{x:Bind ViewModel.PrintSettings.ScaleFactor, Mode=TwoWay}"
Minimum="0.1" Maximum="2.0" StepFrequency="0.1"
Grid.Column="0" />
<TextBlock Text="{x:Bind ViewModel.ScalePercentageText, Mode=OneWay}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="1" />
</Grid>
</StackPanel>
<!-- Margins -->
<StackPanel Spacing="8">
<TextBlock Text="Margins (inches)" FontWeight="SemiBold" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Top" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Center" />
<TextBlock Text="Bottom" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" />
<TextBlock Text="Left" Grid.Column="2" Grid.Row="0" HorizontalAlignment="Center" />
<TextBlock Text="Right" Grid.Column="3" Grid.Row="0" HorizontalAlignment="Center" />
<NumberBox Value="{x:Bind ViewModel.PrintSettings.MarginTop, Mode=TwoWay}"
Minimum="0" Maximum="10" StepFrequency="0.1"
Grid.Column="0" Grid.Row="1" Margin="4" />
<NumberBox Value="{x:Bind ViewModel.PrintSettings.MarginBottom, Mode=TwoWay}"
Minimum="0" Maximum="10" StepFrequency="0.1"
Grid.Column="1" Grid.Row="1" Margin="4" />
<NumberBox Value="{x:Bind ViewModel.PrintSettings.MarginLeft, Mode=TwoWay}"
Minimum="0" Maximum="10" StepFrequency="0.1"
Grid.Column="2" Grid.Row="1" Margin="4" />
<NumberBox Value="{x:Bind ViewModel.PrintSettings.MarginRight, Mode=TwoWay}"
Minimum="0" Maximum="10" StepFrequency="0.1"
Grid.Column="3" Grid.Row="1" Margin="4" />
</Grid>
</StackPanel>
<!-- Print Options -->
<StackPanel Spacing="8">
<TextBlock Text="Options" FontWeight="SemiBold" />
<CheckBox Content="Print backgrounds"
IsChecked="{x:Bind ViewModel.PrintSettings.ShouldPrintBackgrounds, Mode=TwoWay}" />
<CheckBox Content="Print selection only"
IsChecked="{x:Bind ViewModel.PrintSettings.ShouldPrintSelectionOnly, Mode=TwoWay}" />
<CheckBox Content="Print headers and footers"
IsChecked="{x:Bind ViewModel.PrintSettings.ShouldPrintHeaderAndFooter, Mode=TwoWay}" />
</StackPanel>
<!-- Header and Footer -->
<StackPanel Spacing="8" Visibility="{x:Bind ViewModel.PrintSettings.ShouldPrintHeaderAndFooter, Mode=OneWay}">
<TextBlock Text="Header & Footer" FontWeight="SemiBold" />
<TextBox Header="Header Title"
Text="{x:Bind ViewModel.PrintSettings.HeaderTitle, Mode=TwoWay}"
PlaceholderText="Document title" />
<TextBox Header="Footer URI"
Text="{x:Bind ViewModel.PrintSettings.FooterUri, Mode=TwoWay}"
PlaceholderText="Document URL" />
</StackPanel>
<!-- Print Options -->
<StackPanel Spacing="8">
<TextBlock Text="Options" />
<CheckBox Content="Print backgrounds" IsChecked="{x:Bind PrintSettings.ShouldPrintBackgrounds, Mode=TwoWay}" />
<CheckBox Content="Print headers and footers" IsChecked="{x:Bind PrintSettings.ShouldPrintHeaderAndFooter, Mode=TwoWay}" />
</StackPanel> </StackPanel>
</ScrollViewer> </StackPanel>
</ContentDialog> </ContentDialog>
+113 -46
View File
@@ -1,7 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing.Printing;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Serilog;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Printing; using Wino.Core.Domain.Models.Printing;
using Wino.Core.WinUI.Models;
namespace Wino.Core.WinUI.Dialogs; namespace Wino.Core.WinUI.Dialogs;
@@ -10,32 +14,40 @@ namespace Wino.Core.WinUI.Dialogs;
/// </summary> /// </summary>
public sealed partial class PrintDialog : ContentDialog public sealed partial class PrintDialog : ContentDialog
{ {
/// <summary> public WebView2PrintSettingsModel PrintSettings { get; set; } = new WebView2PrintSettingsModel();
/// The ViewModel that handles the dialog's data binding and logic.
/// </summary>
public PrintDialogViewModel ViewModel { get; }
/// <summary>
/// Gets the configured print settings from the dialog.
/// </summary>
public WebView2PrintSettingsModel PrintSettings => ViewModel.PrintSettings;
public PrintDialog() public PrintDialog()
{ {
this.InitializeComponent(); this.InitializeComponent();
ViewModel = new PrintDialogViewModel();
ViewModel.Initialize();
} }
/// <summary> /// <summary>
/// Initializes the dialog with existing print settings. /// Initializes the dialog with existing print settings.
/// </summary> /// </summary>
/// <param name="printSettings">The initial print settings to load.</param> /// <param name="printSettings">The initial print settings to load.</param>
public PrintDialog(WebView2PrintSettingsModel printSettings) public PrintDialog(WebView2PrintSettingsModel printSettings = null)
{ {
if (printSettings != null) PrintSettings = printSettings;
this.InitializeComponent(); this.InitializeComponent();
ViewModel = new PrintDialogViewModel(); }
ViewModel.Initialize(printSettings);
private void PrintDialog_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) => LoadSettingsToUI(PrintSettings);
private void OrientationRadio_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is RadioButtons radioButtons)
{
PrintSettings.Orientation = (PrintOrientation)radioButtons.SelectedIndex;
}
}
private void PrinterComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is ComboBox comboBox && comboBox.SelectedItem != null)
{
PrintSettings.PrinterName = comboBox.SelectedItem.ToString();
}
} }
/// <summary> /// <summary>
@@ -44,7 +56,85 @@ public sealed partial class PrintDialog : ContentDialog
/// <param name="printers">List of available printer names.</param> /// <param name="printers">List of available printer names.</param>
public void SetAvailablePrinters(IEnumerable<string> printers) public void SetAvailablePrinters(IEnumerable<string> printers)
{ {
ViewModel.SetAvailablePrinters(printers); var printerList = printers?.ToList() ?? new List<string>();
if (this.FindName("PrinterComboBox") is ComboBox printerComboBox)
{
printerComboBox.ItemsSource = printerList;
if (printerList.Any())
{
// Set to first printer or to the one in settings
var targetPrinter = !string.IsNullOrEmpty(PrintSettings.PrinterName)
? PrintSettings.PrinterName
: printerList.First();
var index = printerList.IndexOf(targetPrinter);
printerComboBox.SelectedIndex = index >= 0 ? index : 0;
// Update the settings model with the selected printer
PrintSettings.PrinterName = printerComboBox.SelectedItem?.ToString() ?? string.Empty;
}
}
}
/// <summary>
/// Loads available printers asynchronously and sets them in the dialog.
/// </summary>
public async Task LoadAvailablePrintersAsync()
{
try
{
var printers = await Task.Run(() =>
{
var printerList = new List<string>();
// Get all installed printers using System.Drawing.Printing
foreach (string printerName in PrinterSettings.InstalledPrinters)
{
printerList.Add(printerName);
}
return printerList.AsEnumerable();
});
SetAvailablePrinters(printers);
}
catch (System.Exception ex)
{
// Log the exception if logging is available
Log.Error(ex, "Error getting available printers");
// Set empty list if printer discovery fails
SetAvailablePrinters(Enumerable.Empty<string>());
}
}
private void LoadSettingsToUI(WebView2PrintSettingsModel settings)
{
if (settings == null) return;
// Only handle orientation manually since other properties are bound via x:Bind
if (this.FindName("OrientationRadioButtons") is RadioButtons orientationRadio)
{
orientationRadio.SelectedIndex = (int)settings.Orientation;
}
}
private void UpdateSettingsFromUI()
{
// Most properties are bound via x:Bind, only handle orientation manually
if (this.FindName("OrientationRadioButtons") is RadioButtons orientationRadio)
{
PrintSettings.Orientation = (PrintOrientation)orientationRadio.SelectedIndex;
}
// Also update printer name from ComboBox since it uses ItemsSource binding
if (this.FindName("PrinterComboBox") is ComboBox printerComboBox &&
printerComboBox.SelectedItem != null)
{
PrintSettings.PrinterName = printerComboBox.SelectedItem.ToString();
}
} }
/// <summary> /// <summary>
@@ -53,54 +143,31 @@ public sealed partial class PrintDialog : ContentDialog
/// <returns>True if settings are valid, false otherwise.</returns> /// <returns>True if settings are valid, false otherwise.</returns>
private bool ValidateSettings() private bool ValidateSettings()
{ {
// Validate printer selection // Check if a printer is selected
if (string.IsNullOrWhiteSpace(PrintSettings.PrinterName)) if (this.FindName("PrinterComboBox") is ComboBox printerComboBox &&
printerComboBox.SelectedItem == null)
{ {
// Show error message or set focus to printer selection
return false; return false;
} }
// Validate copies // Copies validation is handled by the bound property with validation in the model
if (PrintSettings.Copies <= 0) if (PrintSettings.Copies <= 0)
{ {
return false; return false;
} }
// Validate page ranges if custom range is specified
if (ViewModel.IsCustomPageRange && !string.IsNullOrWhiteSpace(PrintSettings.PageRanges))
{
// Basic validation for page ranges format
// More comprehensive validation could be added here
var pageRanges = PrintSettings.PageRanges.Trim();
if (string.IsNullOrEmpty(pageRanges))
{
return false;
}
}
// Validate margins
if (PrintSettings.MarginTop < 0 || PrintSettings.MarginBottom < 0 ||
PrintSettings.MarginLeft < 0 || PrintSettings.MarginRight < 0)
{
return false;
}
// Validate scale factor
if (PrintSettings.ScaleFactor < 0.1 || PrintSettings.ScaleFactor > 2.0)
{
return false;
}
return true; return true;
} }
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{ {
// Update settings from UI before validation
UpdateSettingsFromUI();
// Validate settings before closing // Validate settings before closing
if (!ValidateSettings()) if (!ValidateSettings())
{ {
args.Cancel = true; args.Cancel = true;
// Could show error message here
} }
} }
+1 -1
View File
@@ -41,7 +41,7 @@ public static class XamlHelpers
public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible; public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible;
public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
public static bool ReverseBoolConverter(bool value) => !value; public static bool ReverseBoolConverter(bool value) => !value;
public static bool ShouldDisplayPreview(string text) => text.Any(x => char.IsLetter(x)); public static bool ShouldDisplayPreview(string text) => text == null ? false : text.Any(x => char.IsLetter(x));
public static bool CountToBooleanConverter(int value) => value > 0; public static bool CountToBooleanConverter(int value) => value > 0;
public static bool ObjectEquals(object obj1, object obj2) => object.Equals(obj1, obj2); public static bool ObjectEquals(object obj1, object obj2) => object.Equals(obj1, obj2);
public static Visibility CountToVisibilityConverter(int value) => value > 0 ? Visibility.Visible : Visibility.Collapsed; public static Visibility CountToVisibilityConverter(int value) => value > 0 ? Visibility.Visible : Visibility.Collapsed;
@@ -1,30 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Wino.Core.Domain.Models.Printing;
namespace Wino.Core.WinUI.Interfaces;
/// <summary>
/// Service interface for displaying the custom print dialog and managing print settings.
/// </summary>
public interface IPrintDialogService
{
/// <summary>
/// Shows the print dialog and returns the configured print settings.
/// </summary>
/// <param name="initialSettings">Initial print settings to populate the dialog with. If null, default settings will be used.</param>
/// <param name="availablePrinters">List of available printers to show in the dialog. If null or empty, the service should attempt to discover printers.</param>
/// <returns>
/// A task that resolves to the configured WebView2PrintSettingsModel if the user clicked Print,
/// or null if the user cancelled the dialog.
/// </returns>
Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(
WebView2PrintSettingsModel initialSettings = null,
IEnumerable<string> availablePrinters = null);
/// <summary>
/// Gets the list of available printers on the system.
/// </summary>
/// <returns>A task that resolves to a list of available printer names.</returns>
Task<IEnumerable<string>> GetAvailablePrintersAsync();
}
@@ -14,6 +14,7 @@ using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Accounts; using Wino.Core.Domain.Models.Accounts;
using Wino.Core.Domain.Models.Common; using Wino.Core.Domain.Models.Common;
using Wino.Core.Domain.Models.Printing;
using Wino.Core.WinUI.Dialogs; using Wino.Core.WinUI.Dialogs;
using Wino.Core.WinUI.Extensions; using Wino.Core.WinUI.Extensions;
using Wino.Dialogs; using Wino.Dialogs;
@@ -294,4 +295,38 @@ public class DialogServiceBase : IDialogServiceBase
return dialog.Result; return dialog.Result;
} }
public async Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(WebView2PrintSettingsModel initialSettings = null)
{
try
{
// Create the print dialog
var dialog = initialSettings != null
? new PrintDialog(initialSettings)
: new PrintDialog();
// Set the XamlRoot for proper display
dialog.XamlRoot = GetXamlRoot();
// Get available printers asynchronously when the dialog is loaded
dialog.Loaded += async (sender, e) =>
{
await dialog.LoadAvailablePrintersAsync();
};
// Show the dialog
var result = await HandleDialogPresentationAsync(dialog);
// Return the settings if user clicked Print, otherwise null
return result == ContentDialogResult.Primary
? dialog.PrintSettings
: null;
}
catch (Exception ex)
{
// Log the exception if logging is available
Log.Error(ex, "Error showing print dialog");
return null;
}
}
} }
@@ -1,93 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Drawing.Printing;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.UI.Xaml;
using Wino.Core.Domain.Models.Printing;
using Wino.Core.WinUI.Dialogs;
using Wino.Core.WinUI.Interfaces;
namespace Wino.Core.WinUI.Services;
/// <summary>
/// Service implementation for displaying the custom print dialog and managing print settings.
/// </summary>
public class PrintDialogService : IPrintDialogService
{
/// <summary>
/// Shows the print dialog and returns the configured print settings.
/// </summary>
/// <param name="initialSettings">Initial print settings to populate the dialog with. If null, default settings will be used.</param>
/// <param name="availablePrinters">List of available printers to show in the dialog. If null or empty, the service will discover printers.</param>
/// <returns>
/// A task that resolves to the configured WebView2PrintSettingsModel if the user clicked Print,
/// or null if the user cancelled the dialog.
/// </returns>
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
Justification = "GetProperty is used for backward compatibility and gracefully handles failures")]
public async Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(
WebView2PrintSettingsModel initialSettings = null,
IEnumerable<string> availablePrinters = null)
{
try
{
// Note: XamlRoot will be set by the calling code when showing the dialog
// Create the print dialog
var dialog = initialSettings != null
? new PrintDialog(initialSettings)
: new PrintDialog();
// The XamlRoot will be set by the calling code when showing the dialog
// Get available printers if not provided
var printers = availablePrinters ?? await GetAvailablePrintersAsync();
dialog.SetAvailablePrinters(printers);
// Show the dialog
var result = await dialog.ShowAsync();
// Return the settings if user clicked Print, otherwise null
return result == Microsoft.UI.Xaml.Controls.ContentDialogResult.Primary
? dialog.PrintSettings
: null;
}
catch (Exception ex)
{
// Log the exception if logging is available
System.Diagnostics.Debug.WriteLine($"Error showing print dialog: {ex.Message}");
return null;
}
}
/// <summary>
/// Gets the list of available printers on the system.
/// </summary>
/// <returns>A task that resolves to a list of available printer names.</returns>
public async Task<IEnumerable<string>> GetAvailablePrintersAsync()
{
return await Task.Run(() =>
{
try
{
var printers = new List<string>();
// Get all installed printers using System.Drawing.Printing
foreach (string printerName in PrinterSettings.InstalledPrinters)
{
printers.Add(printerName);
}
return printers.AsEnumerable();
}
catch (Exception ex)
{
// Log the exception if logging is available
System.Diagnostics.Debug.WriteLine($"Error getting available printers: {ex.Message}");
return Enumerable.Empty<string>();
}
});
}
}
@@ -1,6 +1,6 @@
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Wino.Core.WinUI;
using Wino.Core.ViewModels; using Wino.Core.ViewModels;
using Wino.Core.WinUI;
namespace Wino.Views.Abstract; namespace Wino.Views.Abstract;
+14 -6
View File
@@ -26,9 +26,6 @@ public sealed partial class SettingsPage : SettingsPageAbstract, IRecipient<Brea
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
// Re-register the breadcrumb navigation handler after base.OnNavigatedTo unregisters all handlers
WeakReferenceMessenger.Default.Register<BreadcrumbNavigationRequested>(this);
SettingsFrame.Navigate(typeof(SettingOptionsPage), null, new SuppressNavigationTransitionInfo()); SettingsFrame.Navigate(typeof(SettingOptionsPage), null, new SuppressNavigationTransitionInfo());
var initialRequest = new BreadcrumbNavigationRequested(Translator.MenuSettings, WinoPage.SettingOptionsPage); var initialRequest = new BreadcrumbNavigationRequested(Translator.MenuSettings, WinoPage.SettingOptionsPage);
@@ -63,12 +60,23 @@ public sealed partial class SettingsPage : SettingsPageAbstract, IRecipient<Brea
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{ {
// Explicitly unregister our message handlers before base.OnNavigatingFrom calls UnregisterAll
WeakReferenceMessenger.Default.Unregister<BreadcrumbNavigationRequested>(this);
base.OnNavigatingFrom(e); base.OnNavigatingFrom(e);
} }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
WeakReferenceMessenger.Default.Register<BreadcrumbNavigationRequested>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
WeakReferenceMessenger.Default.Unregister<BreadcrumbNavigationRequested>(this);
}
void IRecipient<BreadcrumbNavigationRequested>.Receive(BreadcrumbNavigationRequested message) void IRecipient<BreadcrumbNavigationRequested>.Receive(BreadcrumbNavigationRequested message)
{ {
var pageType = ViewModel.NavigationService.GetPageType(message.PageType); var pageType = ViewModel.NavigationService.GetPageType(message.PageType);
+32
View File
@@ -1037,4 +1037,36 @@ public partial class AppShellViewModel : MailBaseViewModel,
{ {
await MenuItemInvokedOrSelectedAsync(SettingsItem, WinoPage.AppPreferencesPage); await MenuItemInvokedOrSelectedAsync(SettingsItem, WinoPage.AppPreferencesPage);
} }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
Messenger.Register<NavigateManageAccountsRequested>(this);
Messenger.Register<MailtoProtocolMessageRequested>(this);
Messenger.Register<RefreshUnreadCountsMessage>(this);
Messenger.Register<AccountsMenuRefreshRequested>(this);
Messenger.Register<MergedInboxRenamed>(this);
Messenger.Register<LanguageChanged>(this);
Messenger.Register<AccountMenuItemsReordered>(this);
Messenger.Register<AccountSynchronizationProgressUpdatedMessage>(this);
Messenger.Register<NavigateAppPreferencesRequested>(this);
Messenger.Register<AccountFolderConfigurationUpdated>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
Messenger.Unregister<NavigateManageAccountsRequested>(this);
Messenger.Unregister<MailtoProtocolMessageRequested>(this);
Messenger.Unregister<RefreshUnreadCountsMessage>(this);
Messenger.Unregister<AccountsMenuRefreshRequested>(this);
Messenger.Unregister<MergedInboxRenamed>(this);
Messenger.Unregister<LanguageChanged>(this);
Messenger.Unregister<AccountMenuItemsReordered>(this);
Messenger.Unregister<AccountSynchronizationProgressUpdatedMessage>(this);
Messenger.Unregister<NavigateAppPreferencesRequested>(this);
Messenger.Unregister<AccountFolderConfigurationUpdated>(this);
}
} }
+30
View File
@@ -39,4 +39,34 @@ public class MailBaseViewModel : CoreBaseViewModel,
void IRecipient<FolderRenamed>.Receive(FolderRenamed message) => OnFolderRenamed(message.MailItemFolder); void IRecipient<FolderRenamed>.Receive(FolderRenamed message) => OnFolderRenamed(message.MailItemFolder);
void IRecipient<FolderSynchronizationEnabled>.Receive(FolderSynchronizationEnabled message) => OnFolderSynchronizationEnabled(message.MailItemFolder); void IRecipient<FolderSynchronizationEnabled>.Receive(FolderSynchronizationEnabled message) => OnFolderSynchronizationEnabled(message.MailItemFolder);
protected override void RegisterRecipients()
{
base.RegisterRecipients();
Messenger.Register<MailAddedMessage>(this);
Messenger.Register<MailRemovedMessage>(this);
Messenger.Register<MailUpdatedMessage>(this);
Messenger.Register<MailDownloadedMessage>(this);
Messenger.Register<DraftCreated>(this);
Messenger.Register<DraftFailed>(this);
Messenger.Register<DraftMapped>(this);
Messenger.Register<FolderRenamed>(this);
Messenger.Register<FolderSynchronizationEnabled>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
Messenger.Unregister<MailAddedMessage>(this);
Messenger.Unregister<MailRemovedMessage>(this);
Messenger.Unregister<MailUpdatedMessage>(this);
Messenger.Unregister<MailDownloadedMessage>(this);
Messenger.Unregister<DraftCreated>(this);
Messenger.Unregister<DraftFailed>(this);
Messenger.Unregister<DraftMapped>(this);
Messenger.Unregister<FolderRenamed>(this);
Messenger.Unregister<FolderSynchronizationEnabled>(this);
}
} }
@@ -1081,4 +1081,34 @@ public partial class MailListPageViewModel : MailBaseViewModel,
{ {
// MailCollection.UpdateThumbnails(message.Email); // MailCollection.UpdateThumbnails(message.Email);
} }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
Messenger.Register<MailItemNavigationRequested>(this);
Messenger.Register<ActiveMailFolderChangedEvent>(this);
Messenger.Register<MailItemSelectedEvent>(this);
Messenger.Register<MailItemSelectionRemovedEvent>(this);
Messenger.Register<AccountSynchronizationCompleted>(this);
Messenger.Register<NewMailSynchronizationRequested>(this);
Messenger.Register<AccountSynchronizerStateChanged>(this);
Messenger.Register<AccountCacheResetMessage>(this);
Messenger.Register<ThumbnailAdded>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
Messenger.Unregister<MailItemNavigationRequested>(this);
Messenger.Unregister<ActiveMailFolderChangedEvent>(this);
Messenger.Unregister<MailItemSelectedEvent>(this);
Messenger.Unregister<MailItemSelectionRemovedEvent>(this);
Messenger.Unregister<AccountSynchronizationCompleted>(this);
Messenger.Unregister<NewMailSynchronizationRequested>(this);
Messenger.Unregister<AccountSynchronizerStateChanged>(this);
Messenger.Unregister<AccountCacheResetMessage>(this);
Messenger.Unregister<ThumbnailAdded>(this);
}
} }
@@ -20,6 +20,7 @@ using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.MailItem;
using Wino.Core.Domain.Models.Menus; using Wino.Core.Domain.Models.Menus;
using Wino.Core.Domain.Models.Navigation; using Wino.Core.Domain.Models.Navigation;
using Wino.Core.Domain.Models.Printing;
using Wino.Core.Domain.Models.Reader; using Wino.Core.Domain.Models.Reader;
using Wino.Core.Services; using Wino.Core.Services;
using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Data;
@@ -55,7 +56,7 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
// Used in 'Save as' and 'Print' functionality. // Used in 'Save as' and 'Print' functionality.
public Func<string, Task<bool>> SaveHTMLasPDFFunc { get; set; } public Func<string, Task<bool>> SaveHTMLasPDFFunc { get; set; }
public Action ShowPrintUIAction { get; set; } public Func<WebView2PrintSettingsModel, Task<PrintingResult>> DirectPrintFuncAsync { get; set; }
#region Properties #region Properties
@@ -257,7 +258,22 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
} }
else if (operation == MailOperation.Print) else if (operation == MailOperation.Print)
{ {
ShowPrintUI(); var settings = await _dialogService.ShowPrintDialogAsync();
if (settings == null) return;
var printingResult = await DirectPrintFuncAsync.Invoke(settings);
// TODO: More detailed printing result handling.
if (printingResult == PrintingResult.Submitted)
{
_dialogService.InfoBarMessage(Translator.DialogMessage_PrintingSuccessTitle, Translator.DialogMessage_PrintingSuccessMessage, InfoBarMessageType.Success);
}
else if (printingResult == PrintingResult.Failed)
{
_dialogService.InfoBarMessage(Translator.DialogMessage_PrintingFailedTitle, Translator.DialogMessage_PrintingFailedMessage, InfoBarMessageType.Error);
}
} }
else if (operation == MailOperation.ViewMessageSource) else if (operation == MailOperation.ViewMessageSource)
{ {
@@ -682,19 +698,6 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
} }
} }
private void ShowPrintUI()
{
try
{
ShowPrintUIAction?.Invoke();
}
catch (Exception exception)
{
Log.Error(exception, "Failed to print mail.");
_dialogService.InfoBarMessage(string.Empty, exception.Message, InfoBarMessageType.Error);
}
}
private async Task SaveAsAsync() private async Task SaveAsAsync()
{ {
try try
@@ -793,4 +796,20 @@ public partial class MailRenderingPageViewModel : MailBaseViewModel,
} }
}); });
} }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
Messenger.Register<NewMailItemRenderingRequestedEvent>(this);
Messenger.Register<ThumbnailAdded>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
Messenger.Unregister<NewMailItemRenderingRequestedEvent>(this);
Messenger.Unregister<ThumbnailAdded>(this);
}
} }
+8 -3
View File
@@ -15,7 +15,7 @@ namespace Wino.Mail.WinUI;
public partial class App : WinoApplication, IRecipient<NewMailSynchronizationRequested> public partial class App : WinoApplication, IRecipient<NewMailSynchronizationRequested>
{ {
private ISynchronizationManager _synchronizationManager; private ISynchronizationManager? _synchronizationManager;
public App() public App()
{ {
@@ -23,7 +23,7 @@ public partial class App : WinoApplication, IRecipient<NewMailSynchronizationReq
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
WeakReferenceMessenger.Default.Register<NewMailSynchronizationRequested>(this); RegisterRecipients();
} }
#region Dependency Injection #region Dependency Injection
@@ -114,8 +114,13 @@ public partial class App : WinoApplication, IRecipient<NewMailSynchronizationReq
MainWindow.Activate(); MainWindow.Activate();
} }
private void RegisterRecipients()
{
WeakReferenceMessenger.Default.Register<NewMailSynchronizationRequested>(this);
}
public void Receive(NewMailSynchronizationRequested message) public void Receive(NewMailSynchronizationRequested message)
{ {
_synchronizationManager.SynchronizeMailAsync(message.Options); _synchronizationManager?.SynchronizeMailAsync(message.Options);
} }
} }
+47 -11
View File
@@ -9,6 +9,7 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation; using Windows.Foundation;
using Wino.Core.Domain; using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Entities.Mail;
@@ -20,6 +21,7 @@ using Wino.Core.Domain.Models.Navigation;
using Wino.Core.WinUI; using Wino.Core.WinUI;
using Wino.Core.WinUI.Controls; using Wino.Core.WinUI.Controls;
using Wino.Extensions; using Wino.Extensions;
using Wino.Mail.ViewModels.Data;
using Wino.MenuFlyouts; using Wino.MenuFlyouts;
using Wino.MenuFlyouts.Context; using Wino.MenuFlyouts.Context;
using Wino.Messaging.Client.Accounts; using Wino.Messaging.Client.Accounts;
@@ -37,13 +39,27 @@ public sealed partial class AppShell : AppShellAbstract,
IRecipient<InfoBarMessageRequested> IRecipient<InfoBarMessageRequested>
{ {
[GeneratedDependencyProperty] [GeneratedDependencyProperty]
public partial UIElement TopShellContent { get; set; } public partial UIElement? TopShellContent { get; set; }
public AppShell() : base() public AppShell() : base()
{ {
InitializeComponent(); InitializeComponent();
} }
public Frame GetShellFrame() => ShellFrame;
//protected override void OnNavigatedTo(NavigationEventArgs e)
//{
// base.OnNavigatedTo(e);
// WeakReferenceMessenger.Default.Register<InfoBarMessageRequested>(this);
// WeakReferenceMessenger.Default.Register<AccountMenuItemExtended>(this);
// WeakReferenceMessenger.Default.Register<CreateNewMailWithMultipleAccountsRequested>(this);
// WeakReferenceMessenger.Default.Register<NavigateMailFolderEvent>(this);
//}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
}
private async void ItemDroppedOnFolder(object sender, DragEventArgs e) private async void ItemDroppedOnFolder(object sender, DragEventArgs e)
{ {
@@ -66,14 +82,14 @@ public sealed partial class AppShell : AppShellAbstract,
foreach (var item in dragPackage.DraggingMails) foreach (var item in dragPackage.DraggingMails)
{ {
//if (item is MailItemViewModel singleMailItemViewModel) if (item is MailItemViewModel singleMailItemViewModel)
//{ {
// mailCopies.Add(singleMailItemViewModel.MailCopy); mailCopies.Add(singleMailItemViewModel.MailCopy);
//} }
//else if (item is ThreadMailItemViewModel threadViewModel) else if (item is ThreadMailItemViewModel threadViewModel)
//{ {
// mailCopies.AddRange(threadViewModel.GetMailCopies()); mailCopies.AddRange(threadViewModel.ThreadEmails.Select(a => a.MailCopy));
//} }
} }
await ViewModel.PerformMoveOperationAsync(mailCopies, draggingFolder); await ViewModel.PerformMoveOperationAsync(mailCopies, draggingFolder);
@@ -114,7 +130,7 @@ public sealed partial class AppShell : AppShellAbstract,
// Check whether the moving item's account has at least one same as the target folder's account. // Check whether the moving item's account has at least one same as the target folder's account.
var draggedAccountIds = folderMenuItem.HandlingFolders.Select(a => a.MailAccountId); var draggedAccountIds = folderMenuItem.HandlingFolders.Select(a => a.MailAccountId);
if (!dragPackage.DraggingMails.Any(a => draggedAccountIds.Contains(a.AssignedAccount.Id))) return false; if (!dragPackage.DraggingMails.Cast<MailCopy>().Any(a => draggedAccountIds.Contains(a.AssignedAccount.Id))) return false;
return true; return true;
} }
@@ -320,4 +336,24 @@ public sealed partial class AppShell : AppShellAbstract,
ShellFrame.Margin = new Thickness(0); ShellFrame.Margin = new Thickness(0);
} }
} }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
WeakReferenceMessenger.Default.Register<InfoBarMessageRequested>(this);
WeakReferenceMessenger.Default.Register<AccountMenuItemExtended>(this);
WeakReferenceMessenger.Default.Register<CreateNewMailWithMultipleAccountsRequested>(this);
WeakReferenceMessenger.Default.Register<NavigateMailFolderEvent>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
WeakReferenceMessenger.Default.Unregister<InfoBarMessageRequested>(this);
WeakReferenceMessenger.Default.Unregister<AccountMenuItemExtended>(this);
WeakReferenceMessenger.Default.Unregister<CreateNewMailWithMultipleAccountsRequested>(this);
WeakReferenceMessenger.Default.Unregister<NavigateMailFolderEvent>(this);
}
} }
@@ -103,9 +103,19 @@ public sealed partial class NewImapSetupDialog : ContentDialog,
public void StartImapConnectionSetup(MailAccount account) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), account, new DrillInNavigationTransitionInfo()); public void StartImapConnectionSetup(MailAccount account) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), account, new DrillInNavigationTransitionInfo());
public void StartImapConnectionSetup(AccountCreationDialogResult accountCreationDialogResult) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), accountCreationDialogResult, new DrillInNavigationTransitionInfo()); public void StartImapConnectionSetup(AccountCreationDialogResult accountCreationDialogResult) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), accountCreationDialogResult, new DrillInNavigationTransitionInfo());
private void ImapSetupDialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args) => WeakReferenceMessenger.Default.UnregisterAll(this); private void ImapSetupDialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
{
WeakReferenceMessenger.Default.Unregister<ImapSetupNavigationRequested>(this);
WeakReferenceMessenger.Default.Unregister<ImapSetupBackNavigationRequested>(this);
WeakReferenceMessenger.Default.Unregister<ImapSetupDismissRequested>(this);
}
private void ImapSetupDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) => WeakReferenceMessenger.Default.RegisterAll(this); private void ImapSetupDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{
WeakReferenceMessenger.Default.Register<ImapSetupNavigationRequested>(this);
WeakReferenceMessenger.Default.Register<ImapSetupBackNavigationRequested>(this);
WeakReferenceMessenger.Default.Register<ImapSetupDismissRequested>(this);
}
// Don't hide the dialog unless dismiss is requested from the inner pages specifically. // Don't hide the dialog unless dismiss is requested from the inner pages specifically.
private void OnDialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) => args.Cancel = !isDismissRequested; private void OnDialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) => args.Cancel = !isDismissRequested;
+16 -3
View File
@@ -15,7 +15,7 @@ using WinUIEx;
namespace Wino.Mail.WinUI; namespace Wino.Mail.WinUI;
public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient<ApplicationThemeChanged> public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient<ApplicationThemeChanged>, IRecipient<TitleBarShellContentUpdated>
{ {
public IStatePersistanceService StatePersistanceService { get; } = WinoApplication.Current.Services.GetService<IStatePersistanceService>() ?? throw new Exception("StatePersistanceService not registered in DI container."); public IStatePersistanceService StatePersistanceService { get; } = WinoApplication.Current.Services.GetService<IStatePersistanceService>() ?? throw new Exception("StatePersistanceService not registered in DI container.");
public IPreferencesService PreferencesService { get; } = WinoApplication.Current.Services.GetService<IPreferencesService>() ?? throw new Exception("PreferencesService not registered in DI container."); public IPreferencesService PreferencesService { get; } = WinoApplication.Current.Services.GetService<IPreferencesService>() ?? throw new Exception("PreferencesService not registered in DI container.");
@@ -23,8 +23,7 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient
public ShellWindow() public ShellWindow()
{ {
WeakReferenceMessenger.Default.Register<TitleBarShellContentUpdated>(this); RegisterRecipients();
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
InitializeComponent(); InitializeComponent();
@@ -177,10 +176,24 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient
// Clean up system tray // Clean up system tray
_systemTrayService?.Dispose(); _systemTrayService?.Dispose();
UnregisterRecipients();
// Close the window // Close the window
this.Close(); this.Close();
// Exit the application // Exit the application
Application.Current.Exit(); Application.Current.Exit();
} }
private void RegisterRecipients()
{
WeakReferenceMessenger.Default.Register<TitleBarShellContentUpdated>(this);
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
}
private void UnregisterRecipients()
{
WeakReferenceMessenger.Default.Unregister<TitleBarShellContentUpdated>(this);
WeakReferenceMessenger.Default.Unregister<ApplicationThemeChanged>(this);
}
} }
+16 -10
View File
@@ -57,22 +57,12 @@ public sealed partial class MailListPage : MailListPageAbstract,
{ {
WeakReferenceMessenger.Default.Send(new ActiveMailFolderChangedEvent(folderNavigationArgs.BaseFolderMenuItem, folderNavigationArgs.FolderInitLoadAwaitTask)); WeakReferenceMessenger.Default.Send(new ActiveMailFolderChangedEvent(folderNavigationArgs.BaseFolderMenuItem, folderNavigationArgs.FolderInitLoadAwaitTask));
} }
WeakReferenceMessenger.Default.Register<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Register<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Register<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Register<DisposeRenderingFrameRequested>(this);
} }
protected override void OnNavigatedFrom(NavigationEventArgs e) protected override void OnNavigatedFrom(NavigationEventArgs e)
{ {
base.OnNavigatedFrom(e); base.OnNavigatedFrom(e);
WeakReferenceMessenger.Default.Unregister<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Unregister<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Unregister<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Unregister<DisposeRenderingFrameRequested>(this);
// Dispose all WinoListView items. // Dispose all WinoListView items.
// MailListView.Dispose(); // MailListView.Dispose();
@@ -455,6 +445,22 @@ public sealed partial class MailListPage : MailListPageAbstract,
ViewModel.NavigationService.Navigate(WinoPage.IdlePage, null, NavigationReferenceFrame.RenderingFrame, NavigationTransitionType.DrillIn); ViewModel.NavigationService.Navigate(WinoPage.IdlePage, null, NavigationReferenceFrame.RenderingFrame, NavigationTransitionType.DrillIn);
} }
protected override void RegisterRecipients()
{
WeakReferenceMessenger.Default.Register<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Register<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Register<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Register<DisposeRenderingFrameRequested>(this);
}
protected override void UnregisterRecipients()
{
WeakReferenceMessenger.Default.Unregister<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Unregister<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Unregister<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Unregister<DisposeRenderingFrameRequested>(this);
}
private void PageSizeChanged(object sender, SizeChangedEventArgs e) private void PageSizeChanged(object sender, SizeChangedEventArgs e)
{ {
ViewModel.MaxMailListLength = e.NewSize.Width - RENDERING_COLUMN_MIN_WIDTH; ViewModel.MaxMailListLength = e.NewSize.Width - RENDERING_COLUMN_MIN_WIDTH;
+37 -19
View File
@@ -11,7 +11,9 @@ using Microsoft.UI.Xaml.Navigation;
using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.Core;
using Windows.System; using Windows.System;
using Wino.Core.Domain; using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Printing;
using Wino.Core.WinUI.Extensions; using Wino.Core.WinUI.Extensions;
using Wino.Mail.ViewModels.Data; using Wino.Mail.ViewModels.Data;
using Wino.Mail.WinUI; using Wino.Mail.WinUI;
@@ -43,7 +45,7 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
Environment.SetEnvironmentVariable("WEBVIEW2_DEFAULT_BACKGROUND_COLOR", "00FFFFFF"); Environment.SetEnvironmentVariable("WEBVIEW2_DEFAULT_BACKGROUND_COLOR", "00FFFFFF");
Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--enable-features=OverlayScrollbar,msOverlayScrollbarWinStyle,msOverlayScrollbarWinStyleAnimation,msWebView2CodeCache"); Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--enable-features=OverlayScrollbar,msOverlayScrollbarWinStyle,msOverlayScrollbarWinStyleAnimation,msWebView2CodeCache");
ViewModel.ShowPrintUIAction = ShowPrintUI; ViewModel.DirectPrintFuncAsync = DirectPrintAsync;
ViewModel.SaveHTMLasPDFFunc = new Func<string, Task<bool>>((path) => ViewModel.SaveHTMLasPDFFunc = new Func<string, Task<bool>>((path) =>
{ {
@@ -51,19 +53,25 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
}); });
} }
private async void ShowPrintUI() private async Task<PrintingResult> DirectPrintAsync(WebView2PrintSettingsModel settings)
{ {
if (Chromium.CoreWebView2 == null) return; if (Chromium.CoreWebView2 == null) return PrintingResult.Failed;
// TODO: Footer still shows wino.mail/html, there is no way to change it currently. try
// TODO: ShowPrintUI - System doesn't open. {
// TODO: ShowPrintUI - System doesn't open. var nativeSettings = settings.ToCoreWebView2PrintSettings(Chromium.CoreWebView2.Environment);
var res = await Chromium.CoreWebView2.PrintAsync(nativeSettings);
// Set the document title before printing. This title will be used in the print dialog and header. return res switch
await Chromium.CoreWebView2.ExecuteScriptAsync($"document.title = '{ViewModel.Subject}';"); {
var settings = Chromium.CoreWebView2.Environment.CreatePrintSettings(); CoreWebView2PrintStatus.Succeeded => PrintingResult.Submitted,
_ => PrintingResult.Failed,
Chromium.CoreWebView2?.ShowPrintUI(CoreWebView2PrintDialogKind.System); };
}
catch (Exception)
{
return PrintingResult.Failed;
}
} }
public override async void OnEditorThemeChanged() public override async void OnEditorThemeChanged()
@@ -138,10 +146,6 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
{ {
base.OnNavigatedFrom(e); base.OnNavigatedFrom(e);
WeakReferenceMessenger.Default.Unregister<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Unregister<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Unregister<ApplicationThemeChanged>(this);
// Disposing the page. // Disposing the page.
// Make sure the WebView2 is disposed properly. // Make sure the WebView2 is disposed properly.
@@ -171,10 +175,6 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
{ {
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
WeakReferenceMessenger.Default.Register<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Register<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
var anim = ConnectedAnimationService.GetForCurrentView().GetAnimation("WebViewConnectedAnimation"); var anim = ConnectedAnimationService.GetForCurrentView().GetAnimation("WebViewConnectedAnimation");
anim?.TryStart(Chromium); anim?.TryStart(Chromium);
@@ -297,4 +297,22 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
hyperlinkButton.ContextFlyout.ShowAt(hyperlinkButton); hyperlinkButton.ContextFlyout.ShowAt(hyperlinkButton);
} }
} }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
WeakReferenceMessenger.Default.Register<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Register<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
WeakReferenceMessenger.Default.Unregister<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Unregister<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Unregister<ApplicationThemeChanged>(this);
}
} }
+20
View File
@@ -332,4 +332,24 @@ public sealed partial class AppShell : AppShellAbstract,
ShellFrame.Margin = new Thickness(0); ShellFrame.Margin = new Thickness(0);
} }
} }
protected override void RegisterRecipients()
{
base.RegisterRecipients();
WeakReferenceMessenger.Default.Register<InfoBarMessageRequested>(this);
WeakReferenceMessenger.Default.Register<AccountMenuItemExtended>(this);
WeakReferenceMessenger.Default.Register<CreateNewMailWithMultipleAccountsRequested>(this);
WeakReferenceMessenger.Default.Register<NavigateMailFolderEvent>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
WeakReferenceMessenger.Default.Unregister<InfoBarMessageRequested>(this);
WeakReferenceMessenger.Default.Unregister<AccountMenuItemExtended>(this);
WeakReferenceMessenger.Default.Unregister<CreateNewMailWithMultipleAccountsRequested>(this);
WeakReferenceMessenger.Default.Unregister<NavigateMailFolderEvent>(this);
}
} }
+12 -2
View File
@@ -102,9 +102,19 @@ public sealed partial class NewImapSetupDialog : ContentDialog,
public void StartImapConnectionSetup(MailAccount account) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), account, new DrillInNavigationTransitionInfo()); public void StartImapConnectionSetup(MailAccount account) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), account, new DrillInNavigationTransitionInfo());
public void StartImapConnectionSetup(AccountCreationDialogResult accountCreationDialogResult) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), accountCreationDialogResult, new DrillInNavigationTransitionInfo()); public void StartImapConnectionSetup(AccountCreationDialogResult accountCreationDialogResult) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), accountCreationDialogResult, new DrillInNavigationTransitionInfo());
private void ImapSetupDialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args) => WeakReferenceMessenger.Default.UnregisterAll(this); private void ImapSetupDialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
{
WeakReferenceMessenger.Default.Unregister<ImapSetupNavigationRequested>(this);
WeakReferenceMessenger.Default.Unregister<ImapSetupBackNavigationRequested>(this);
WeakReferenceMessenger.Default.Unregister<ImapSetupDismissRequested>(this);
}
private void ImapSetupDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) => WeakReferenceMessenger.Default.RegisterAll(this); private void ImapSetupDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{
WeakReferenceMessenger.Default.Register<ImapSetupNavigationRequested>(this);
WeakReferenceMessenger.Default.Register<ImapSetupBackNavigationRequested>(this);
WeakReferenceMessenger.Default.Register<ImapSetupDismissRequested>(this);
}
// Don't hide the dialog unless dismiss is requested from the inner pages specifically. // Don't hide the dialog unless dismiss is requested from the inner pages specifically.
private void OnDialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) => args.Cancel = !isDismissRequested; private void OnDialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) => args.Cancel = !isDismissRequested;