Различные мои приложения WPF отображают FlowDocument. Я могу распечатать их, с помощью подхода, описанного в ответе на Печать WPF FlowDocument.
Теперь я хотел бы добавить возможность "предварительного просмотра". В нормальном случае я печатаю FlowDocument, который отображен в Окне, и таким образом, мне не был бы нужен Предварительный просмотр затем. Но в некоторых случаях FlowDocument для печати создается на лету в памяти. И в этих случаях я хотел бы отобразить его перед печатью.
Теперь, я могу, конечно, вытолкать новое окно и отобразить FlowDocument, но
Я хочу, чтобы предварительный просмотр действительно чувствовал, что это - часть операции печати и не только другое Окно в приложении.
Я не хочу нормальный FlowDocument в FlowDocumentScrollViewer. Вместо того, чтобы быть "любым размером", это должно ограничиваться к размеру бумаги, определенного отношения HxW, и нумероваться страницы.
Предложения?
я должен просто использовать стандартное Окно, и в этом случае, как я удостоверяюсь, что FlowDocument в надлежащем отношении?
существует ли более "интегрированный" способ сделать предварительный просмотр в рамках PrintDialog UI, который является частью Windows?
Спасибо
В Oracle наиболее полезным является сеанс v $ session
о ожидании запущенных сеансов, это означает, что сеанс делает в этот момент (чтение с диска, ожидание блокировки,...)
Я разбиваю свои проекты по темам, один каталог для темы:
menu_planner
src
recipes
debug -- contains debug object files and libraries
release -- contains release object files and libraries
obsolete -- contains obsolete source files
ingredients
debug -- contains debug object files and libraries
release -- contains release object files and libraries
obsolete -- contains obsolete source files
references
debug -- contains debug object files and libraries
release -- contains release object files and libraries
obsolete -- contains obsolete source files
meals
debug -- contains debug object files and libraries
release -- contains release object files and libraries
obsolete -- contains obsolete source files
menus
debug -- contains debug object files and libraries
release -- contains release object files and libraries
obsolete -- contains obsolete source files
docs
designs
Мой опыт работы с C и C++ показал мне, что заголовочные и исходные файлы должны находиться в одном каталоге. Часто найти файл заголовка сложнее, если он находится не в том же каталоге, что и исходный файл.
Один каталог (папка) на концепцию является хорошей идеей. Любая сложная или составная концепция должна быть разделена на несколько папок или концепций.
Я также научился создавать библиотеки. Я использую библиотеки, чтобы содержать код, который мало меняется. Операция связывания выполняется с библиотеками быстрее, чем с каталогами файлов объектов.
Однако рабочие места (а.к.а. магазины) могут иметь различные правила стиля, которые должны соблюдаться.
-121--3702131-Взяв подсказку из комментария, добавленного к моему вопросу, я сделал следующее:
private string _previewWindowXaml =
@"<Window
xmlns ='http://schemas.microsoft.com/netfx/2007/xaml/presentation'
xmlns:x ='http://schemas.microsoft.com/winfx/2006/xaml'
Title ='Print Preview - @@TITLE'
Height ='200'
Width ='300'
WindowStartupLocation ='CenterOwner'>
<DocumentViewer Name='dv1'/>
</Window>";
internal void DoPreview(string title)
{
string fileName = System.IO.Path.GetRandomFileName();
FlowDocumentScrollViewer visual = (FlowDocumentScrollViewer)(_parent.FindName("fdsv1"));
try
{
// write the XPS document
using (XpsDocument doc = new XpsDocument(fileName, FileAccess.ReadWrite))
{
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
writer.Write(visual);
}
// Read the XPS document into a dynamically generated
// preview Window
using (XpsDocument doc = new XpsDocument(fileName, FileAccess.Read))
{
FixedDocumentSequence fds = doc.GetFixedDocumentSequence();
string s = _previewWindowXaml;
s = s.Replace("@@TITLE", title.Replace("'", "'"));
using (var reader = new System.Xml.XmlTextReader(new StringReader(s)))
{
Window preview = System.Windows.Markup.XamlReader.Load(reader) as Window;
DocumentViewer dv1 = LogicalTreeHelper.FindLogicalNode(preview, "dv1") as DocumentViewer;
dv1.Document = fds as IDocumentPaginatorSource;
preview.ShowDialog();
}
}
}
finally
{
if (File.Exists(fileName))
{
try
{
File.Delete(fileName);
}
catch
{
}
}
}
}
Что он делает: он фактически печатает содержимое визуала в документ XPS. Затем он загружает "распечатанный" документ XPS и отображает его в очень простом файле XAML, который хранится в виде строки, а не в виде отдельного модуля и загружается динамически во время выполнения. В результирующем окне имеются кнопки DocumentViewer: print, adjust-to-max-page-width и т. д.
Я также добавил код, чтобы скрыть поле поиска. См. этот ответ на WPF: Как удалить поле поиска в DocumentViewer?
Эффект таков:
XpsDocument можно найти в библиотеке ReachFramework, а XpsDocumentWriter - в библиотеке System.Printing, которые должны быть добавлены в качестве ссылок на проект
Элемент управления FlowDocumentPageViewer является основой для " предварительный просмотр », использованный в одном из наших проектов. Вот XAML элемента управления DocumentPreviewer (извиняюсь за длину - XAML не является кратким):
<Control
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:sys="clr-namespace:System;assembly=mscorlib"
xmlns:l="clr-namespace:Tyler.ComPort.UI"
mc:Ignorable="d"
x:Class="Tyler.ComPort.UI.DocumentPreviewer"
x:Name="UserControl"
Background="Gray"
d:DesignWidth="640" d:DesignHeight="480">
<Control.Resources>
<ObjectDataProvider x:Key="ViewStyles" MethodName="GetValues" ObjectType="{x:Type sys:Enum}" >
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="l:ViewType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<l:EnumMatchVisibilityConverter x:Key="EnumVisibilityConverter" />
</Control.Resources>
<Control.Template>
<ControlTemplate>
<ControlTemplate.Triggers>
<Trigger Property="l:DocumentPreviewer.ViewType">
<Trigger.Value>
<l:ViewType>Actual</l:ViewType>
</Trigger.Value>
<Trigger.Setters>
<Setter TargetName="ScrollViewer" Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter TargetName="ScrollViewer" Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter TargetName="Viewbox" Property="Viewbox.Stretch" Value="None" />
</Trigger.Setters>
</Trigger>
<Trigger Property="l:DocumentPreviewer.ViewType">
<Trigger.Value>
<l:ViewType>Fit</l:ViewType>
</Trigger.Value>
<Trigger.Setters>
<Setter TargetName="ScrollViewer" Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter TargetName="ScrollViewer" Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled" />
<Setter TargetName="Viewbox" Property="Viewbox.Stretch" Value="Uniform" />
</Trigger.Setters>
</Trigger>
<Trigger Property="l:DocumentPreviewer.ViewType">
<Trigger.Value>
<l:ViewType>Wide</l:ViewType>
</Trigger.Value>
<Trigger.Setters>
<Setter TargetName="ScrollViewer" Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter TargetName="ScrollViewer" Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter TargetName="Viewbox" Property="Viewbox.Stretch" Value="UniformToFill" />
</Trigger.Setters>
</Trigger>
</ControlTemplate.Triggers>
<DockPanel>
<ToolBar DockPanel.Dock="Top">
<Button Command="{x:Static ApplicationCommands.Print}" CommandTarget="{Binding ElementName=PageViewer}" Content="Print..." />
<Separator />
<Button Command="{x:Static NavigationCommands.PreviousPage}" CommandTarget="{Binding ElementName=PageViewer}" Content="< Previous" />
<Button Command="{x:Static NavigationCommands.NextPage}" CommandTarget="{Binding ElementName=PageViewer}" Content="Next >" />
<Separator />
<l:ToolBarButtonGroup
ItemsSource="{Binding Source={StaticResource ViewStyles}}"
SelectedItem="{Binding ViewType, ElementName=UserControl}"
IsSynchronizedWithCurrentItem="True"
>
<l:ToolBarButtonGroup.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" ToolTip="{Binding}" SnapsToDevicePixels="True">
<Image Source="../Images/actual.png" Visibility="{Binding Converter={StaticResource EnumVisibilityConverter}, ConverterParameter=Actual}" />
<Image Source="../Images/fit.png" Visibility="{Binding Converter={StaticResource EnumVisibilityConverter}, ConverterParameter=Fit}" />
<Image Source="../Images/wide.png" Visibility="{Binding Converter={StaticResource EnumVisibilityConverter}, ConverterParameter=Wide}" />
</StackPanel>
</DataTemplate>
</l:ToolBarButtonGroup.ItemTemplate>
</l:ToolBarButtonGroup>
</ToolBar>
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled">
<Border
BorderBrush="Black"
BorderThickness="1"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Background="White"
Margin="10">
<Viewbox x:Name="Viewbox" Stretch="Uniform">
<FlowDocumentPageViewer
x:Name="PageViewer"
Document="{Binding Document, ElementName=UserControl}"
Zoom="100"
MinZoom="20"
MaxZoom="200">
<FlowDocumentPageViewer.Template>
<ControlTemplate TargetType="{x:Type FlowDocumentPageViewer}">
<AdornerDecorator>
<DocumentPageView FlowDocumentPageViewer.IsMasterPage="True" />
</AdornerDecorator>
</ControlTemplate>
</FlowDocumentPageViewer.Template>
</FlowDocumentPageViewer>
</Viewbox>
</Border>
</ScrollViewer>
</DockPanel>
</ControlTemplate>
</Control.Template>
</Control>
Где вы можете разместить такой элемент управления, зависит от вас (и вашего приложения), конечно, но в нашем приложении есть поведение аналогично типичному приложению Office, где вы можете либо печатать напрямую, либо предварительно просматривать (что показывает интерфейс выше) и печатать оттуда.