edit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.vs/
|
||||
**/bin/
|
||||
**/obj/
|
||||
3
CLITPdfReader.slnx
Normal file
3
CLITPdfReader.slnx
Normal file
@@ -0,0 +1,3 @@
|
||||
<Solution>
|
||||
<Project Path="CLITPdfReader/CLITPdfReader.csproj" />
|
||||
</Solution>
|
||||
7
CLITPdfReader/App.xaml
Normal file
7
CLITPdfReader/App.xaml
Normal file
@@ -0,0 +1,7 @@
|
||||
<Application x:Class="CLITPdfReader.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
22
CLITPdfReader/App.xaml.cs
Normal file
22
CLITPdfReader/App.xaml.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
|
||||
namespace CLITPdfReader;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
string? initialPdfPath = null;
|
||||
|
||||
if (e.Args.Length > 0 && File.Exists(e.Args[0]))
|
||||
{
|
||||
initialPdfPath = e.Args[0];
|
||||
}
|
||||
|
||||
MainWindow = new MainWindow(initialPdfPath);
|
||||
MainWindow.Show();
|
||||
}
|
||||
}
|
||||
10
CLITPdfReader/AssemblyInfo.cs
Normal file
10
CLITPdfReader/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly:ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
15
CLITPdfReader/CLITPdfReader.csproj
Normal file
15
CLITPdfReader/CLITPdfReader.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net10.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3856.49" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
78
CLITPdfReader/MainWindow.xaml
Normal file
78
CLITPdfReader/MainWindow.xaml
Normal file
@@ -0,0 +1,78 @@
|
||||
<Window x:Class="CLITPdfReader.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
|
||||
mc:Ignorable="d"
|
||||
Title="CLIT PDF Reader"
|
||||
Width="1200"
|
||||
Height="800"
|
||||
MinWidth="760"
|
||||
MinHeight="520"
|
||||
Loaded="Window_Loaded"
|
||||
AllowDrop="True"
|
||||
DragOver="Window_DragOver"
|
||||
Drop="Window_Drop">
|
||||
<DockPanel>
|
||||
<Border DockPanel.Dock="Top"
|
||||
Background="#FFF4F4F5"
|
||||
BorderBrush="#FFE2E8F0"
|
||||
BorderThickness="0,0,0,1">
|
||||
<ToolBarTray>
|
||||
<ToolBar FontSize="14"
|
||||
Padding="6,2"
|
||||
MinHeight="34">
|
||||
<Button Command="ApplicationCommands.Open"
|
||||
Padding="10,3"
|
||||
Margin="0,0,8,0">Открыть PDF</Button>
|
||||
<Button Command="ApplicationCommands.Print"
|
||||
Padding="10,3"
|
||||
Margin="0,0,16,0">Печать</Button>
|
||||
<Separator />
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
FontWeight="SemiBold"
|
||||
Text="Файл:"
|
||||
Margin="12,0,8,0" />
|
||||
<TextBlock x:Name="CurrentFileTextBlock"
|
||||
VerticalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Width="760"
|
||||
Foreground="#FF334155"
|
||||
Text="PDF не открыт" />
|
||||
</ToolBar>
|
||||
</ToolBarTray>
|
||||
</Border>
|
||||
|
||||
<StatusBar DockPanel.Dock="Bottom">
|
||||
<StatusBarItem>
|
||||
<TextBlock x:Name="StatusTextBlock" Text="Готово к открытию PDF." />
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
|
||||
<Grid Background="#FFF8FAFC">
|
||||
<wv2:WebView2 x:Name="PdfView" />
|
||||
|
||||
<Border x:Name="PlaceholderPanel"
|
||||
Background="#FFF8FAFC"
|
||||
Visibility="Visible">
|
||||
<StackPanel MaxWidth="520"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock x:Name="PlaceholderTitleTextBlock"
|
||||
Text="Откройте PDF-файл"
|
||||
FontSize="28"
|
||||
FontWeight="SemiBold"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,12" />
|
||||
<TextBlock x:Name="PlaceholderDescriptionTextBlock"
|
||||
Text="Используйте кнопку «Открыть PDF», горячую клавишу Ctrl+O или просто перетащите файл в окно."
|
||||
TextAlignment="Center"
|
||||
Foreground="#FF475569"
|
||||
FontSize="15"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
180
CLITPdfReader/MainWindow.xaml.cs
Normal file
180
CLITPdfReader/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace CLITPdfReader;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private const string AppTitle = "CLIT PDF Reader";
|
||||
private readonly string? _initialPdfPath;
|
||||
private bool _isBrowserReady;
|
||||
private string? _currentPdfPath;
|
||||
|
||||
public MainWindow(string? initialPdfPath = null)
|
||||
{
|
||||
_initialPdfPath = initialPdfPath;
|
||||
InitializeComponent();
|
||||
|
||||
CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, OpenCommand_Executed));
|
||||
CommandBindings.Add(new CommandBinding(ApplicationCommands.Print, PrintCommand_Executed, PrintCommand_CanExecute));
|
||||
InputBindings.Add(new KeyBinding(ApplicationCommands.Open, new KeyGesture(Key.O, ModifierKeys.Control)));
|
||||
InputBindings.Add(new KeyBinding(ApplicationCommands.Print, new KeyGesture(Key.P, ModifierKeys.Control)));
|
||||
}
|
||||
|
||||
private async void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await EnsureBrowserReadyAsync();
|
||||
|
||||
if (_isBrowserReady && !string.IsNullOrWhiteSpace(_initialPdfPath))
|
||||
{
|
||||
OpenPdf(_initialPdfPath);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> EnsureBrowserReadyAsync()
|
||||
{
|
||||
if (_isBrowserReady)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await PdfView.EnsureCoreWebView2Async();
|
||||
PdfView.CoreWebView2.Settings.HiddenPdfToolbarItems = CoreWebView2PdfToolbarItems.None;
|
||||
_isBrowserReady = true;
|
||||
UpdateCommandState();
|
||||
return true;
|
||||
}
|
||||
catch (WebView2RuntimeNotFoundException)
|
||||
{
|
||||
ShowPlaceholder(
|
||||
"WebView2 Runtime не найден",
|
||||
"Установите Microsoft Edge WebView2 Runtime, после чего приложение сможет отображать PDF."
|
||||
);
|
||||
StatusTextBlock.Text = "Не найден Microsoft Edge WebView2 Runtime.";
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowPlaceholder(
|
||||
"Не удалось инициализировать просмотр",
|
||||
ex.Message
|
||||
);
|
||||
StatusTextBlock.Text = "Ошибка инициализации WebView2.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async void OpenCommand_Executed(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
if (!await EnsureBrowserReadyAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var openFileDialog = new OpenFileDialog
|
||||
{
|
||||
Title = "Выберите PDF-файл",
|
||||
Filter = "PDF files (*.pdf)|*.pdf|All files (*.*)|*.*",
|
||||
Multiselect = false
|
||||
};
|
||||
|
||||
if (openFileDialog.ShowDialog(this) == true)
|
||||
{
|
||||
OpenPdf(openFileDialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
|
||||
{
|
||||
e.CanExecute = _isBrowserReady && !string.IsNullOrWhiteSpace(_currentPdfPath);
|
||||
}
|
||||
|
||||
private void PrintCommand_Executed(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
if (!_isBrowserReady || PdfView.CoreWebView2 is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PdfView.CoreWebView2.ShowPrintUI(CoreWebView2PrintDialogKind.Browser);
|
||||
}
|
||||
|
||||
private void Window_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
e.Effects = HasSinglePdfFile(e.Data) ? DragDropEffects.Copy : DragDropEffects.None;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private async void Window_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (!HasSinglePdfFile(e.Data))
|
||||
{
|
||||
StatusTextBlock.Text = "Поддерживаются только PDF-файлы.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await EnsureBrowserReadyAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var droppedFiles = e.Data.GetData(DataFormats.FileDrop) as string[];
|
||||
|
||||
if (droppedFiles is { Length: 1 })
|
||||
{
|
||||
OpenPdf(droppedFiles[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasSinglePdfFile(IDataObject dataObject)
|
||||
{
|
||||
if (!dataObject.GetDataPresent(DataFormats.FileDrop))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var files = dataObject.GetData(DataFormats.FileDrop) as string[];
|
||||
return files is { Length: 1 } &&
|
||||
File.Exists(files[0]) &&
|
||||
string.Equals(Path.GetExtension(files[0]), ".pdf", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private void OpenPdf(string pdfPath)
|
||||
{
|
||||
if (!File.Exists(pdfPath))
|
||||
{
|
||||
ShowPlaceholder("Файл не найден", pdfPath);
|
||||
StatusTextBlock.Text = "Не удалось открыть файл.";
|
||||
return;
|
||||
}
|
||||
|
||||
_currentPdfPath = pdfPath;
|
||||
PdfView.CoreWebView2.Navigate(new Uri(pdfPath).AbsoluteUri);
|
||||
PlaceholderPanel.Visibility = Visibility.Collapsed;
|
||||
CurrentFileTextBlock.Text = pdfPath;
|
||||
Title = $"{Path.GetFileName(pdfPath)} - {AppTitle}";
|
||||
StatusTextBlock.Text = "PDF открыт. Для печати нажмите Ctrl+P.";
|
||||
UpdateCommandState();
|
||||
}
|
||||
|
||||
private void ShowPlaceholder(string title, string description)
|
||||
{
|
||||
PlaceholderTitleTextBlock.Text = title;
|
||||
PlaceholderDescriptionTextBlock.Text = description;
|
||||
PlaceholderPanel.Visibility = Visibility.Visible;
|
||||
CurrentFileTextBlock.Text = "PDF не открыт";
|
||||
Title = AppTitle;
|
||||
_currentPdfPath = null;
|
||||
UpdateCommandState();
|
||||
}
|
||||
|
||||
private void UpdateCommandState()
|
||||
{
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user