2010-02-23 7 views
11

광산의 다양한 WPF 응용 프로그램에서 FlowDocument를 표시합니다. the answer to Printing a WPF FlowDocument에 설명 된 방법을 사용하여 인쇄 할 수 있습니다.WPF 응용 프로그램에서 FlowDocument의 "인쇄 미리보기"를 어떻게 만들 수 있습니까?

이제 "인쇄 미리보기"기능을 추가하고 싶습니다. 정상적인 경우 Window에 표시되는 FlowDocument를 인쇄하므로 인쇄 미리보기가 필요 없습니다. 그러나 일부 경우에는 인쇄 할 FlowDocument가 메모리에서 직접 작성됩니다. 이 경우 인쇄하기 전에 표시하고 싶습니다. 이제

, 나는 확실히 새 창을 팝업하고 FlowDocument를 표시 할 수 있지만

  1. 나는 그것이 단지 다른 창 인쇄 작업의 일부입니다, 그리고 정말 좋아 을 느낄 수있는 미리보기를 할 수 있습니다 앱.

  2. FlowDocumentScrollViewer에 일반적인 FlowDocument가 필요하지 않습니다. "모든 크기"가 아니라 용지 크기, 특정 HxW 비율 및 페이지 매김에 제약을 받아야합니다.

제안 사항?

  • 표준 Window를 사용해야하나요?이 경우 FlowDocument가 적절한 비율로 유지되는 것을 어떻게 보장할까요?

  • Windows의 일부인 PrintDialog UI의 범위 내에서 미리보기를 수행하는 데 "통합 된"방법이 있습니까?

감사

+1

안녕 Cheeso,이 대답은 http://stackoverflow.com/questions/584551/how-do-i-print-preview-when-using-a -documentpaginator-to-print/587962 # 587962 XpsDocument를 표준 창과 결합하여 사용할 것을 제안합니다 ... 이미 링크를 보았 기 때문에 대답으로 쓰고 싶지 않습니다. 단지를 위해서. 건배 :) – Anvaka

답변

19

내 질문에 추가, 내가 이런 짓을 :

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("'", "&apos;")); 

      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 버튼이 있습니다 : 인쇄, 최대 페이지 폭 조정 등.

검색 상자를 숨기는 코드도 추가했습니다. 내가 어떻게했는지는 this answer to WPF: How can I remove the searchbox in a DocumentViewer?을 참조하십시오.

영향이 같다 :

alt text http://i48.tinypic.com/2hzkfat.jpg

XpsDocument는 ReachFramework DLL을 발견 할 수 있고, XpsDocumentWriter는 시스템에서 발견 될 수있다.dll을 모두 프로젝트에 대한 참조로 추가해야합니다.

+2

내 프로젝트에서 XpsDocument를 찾을 수 없어 해결할 수 없기 때문에 코드를 사용할 수 없습니다. 내 프로젝트에 어떤 참조를 추가해야합니까? – icaptan

+1

ReachFramework 및 System.Printing에 대한 참조를 Cheeso 상태로 추가 한 다음'using using System.Windows.Xps; System.Windows.Xps.Packaging 사용; 포함하려면 System.Printing;을 사용하십시오. 내 문제없이 컴파일됩니다. –

+2

_parent 란 무엇입니까? –

2

은 "FlowDocumentPageViewer"컨트롤은 우리의 프로젝트 중 하나에서 사용되는 "미리보기"컨트롤의 기초가된다. 당신이 그런 컨트롤을 넣을 수

<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="&lt; Previous" /> 
        <Button Command="{x:Static NavigationCommands.NextPage}" CommandTarget="{Binding ElementName=PageViewer}" Content="Next &gt;" /> 
        <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> 

당신이 (당신의 응용 프로그램) 과정에 달려있다, 그러나 - 여기에 "DocumentPreviewer"컨트롤의 XAML은 (길이에 대한 사과는 XAML은 간결하지 않습니다) 우리의 응용 프로그램은 당신이 직접 인쇄하거나 미리보기 (위의 인터페이스를 보여줍니다) 및 인쇄 할 수있는 전형적인 Office 응용 프로그램과 비슷한 동작을합니다. 댓글에서 힌트를 촬영

+0

확실히 재미 있지만 모든 코드를 소유하고 관리하고 싶지 않습니다! 나는 더 간단한 방법을 원했다. 여기 내가 어떻게 했어 : http://stackoverflow.com/questions/2322064/how-can-i-produce-a-print-preview-of-a-flowdocument-in-a-wpf-application/2322751#2322751 – Cheeso

관련 문제