Custom print dialog.

This commit is contained in:
Burak Kaan Köse
2025-10-20 21:10:29 +02:00
parent baf4141773
commit 4191b7314f
13 changed files with 1432 additions and 0 deletions
+220
View File
@@ -0,0 +1,220 @@
<ContentDialog x:Class="Wino.Core.WinUI.Dialogs.PrintDialog"
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"
mc:Ignorable="d"
Title="Print Settings"
PrimaryButtonText="Print"
SecondaryButtonText="Cancel"
DefaultButton="Primary"
MinWidth="600"
MinHeight="500"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick">
<ScrollViewer>
<StackPanel Spacing="16" Margin="20">
<!-- Printer Selection -->
<StackPanel Spacing="8">
<TextBlock Text="Printer" FontWeight="SemiBold" />
<ComboBox x:Name="PrinterComboBox"
ItemsSource="{x:Bind ViewModel.AvailablePrinters, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.PrintSettings.PrinterName, Mode=TwoWay}"
Header="Select Printer"
HorizontalAlignment="Stretch" />
</StackPanel>
<!-- Print Options Grid -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Left Column -->
<StackPanel Grid.Column="0" Spacing="16">
<!-- Copies -->
<StackPanel Spacing="8">
<TextBlock Text="Copies" FontWeight="SemiBold" />
<NumberBox Value="{x:Bind ViewModel.PrintSettings.Copies, Mode=TwoWay}"
Minimum="1" Maximum="999"
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>
</StackPanel>
</ScrollViewer>
</ContentDialog>
+111
View File
@@ -0,0 +1,111 @@
using System.Collections.Generic;
using Microsoft.UI.Xaml.Controls;
using Wino.Core.Domain.Models.Printing;
using Wino.Core.WinUI.Models;
namespace Wino.Core.WinUI.Dialogs;
/// <summary>
/// Custom print dialog for configuring WebView2 print settings.
/// </summary>
public sealed partial class PrintDialog : ContentDialog
{
/// <summary>
/// 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()
{
this.InitializeComponent();
ViewModel = new PrintDialogViewModel();
ViewModel.Initialize();
}
/// <summary>
/// Initializes the dialog with existing print settings.
/// </summary>
/// <param name="printSettings">The initial print settings to load.</param>
public PrintDialog(WebView2PrintSettingsModel printSettings)
{
this.InitializeComponent();
ViewModel = new PrintDialogViewModel();
ViewModel.Initialize(printSettings);
}
/// <summary>
/// Sets the list of available printers for the dialog.
/// </summary>
/// <param name="printers">List of available printer names.</param>
public void SetAvailablePrinters(IEnumerable<string> printers)
{
ViewModel.SetAvailablePrinters(printers);
}
/// <summary>
/// Validates the current print settings before closing the dialog.
/// </summary>
/// <returns>True if settings are valid, false otherwise.</returns>
private bool ValidateSettings()
{
// Validate printer selection
if (string.IsNullOrWhiteSpace(PrintSettings.PrinterName))
{
// Show error message or set focus to printer selection
return false;
}
// Validate copies
if (PrintSettings.Copies <= 0)
{
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;
}
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
// Validate settings before closing
if (!ValidateSettings())
{
args.Cancel = true;
// Could show error message here
}
}
private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
// Cancel was clicked, no validation needed
}
}