PrintDialog.PrintVisual для неактивных визуальных элементов? - PullRequest
2 голосов
/ 04 июня 2019

Введение

У меня есть приложение с MainWindow (MVVM), состоящее из TabViewer с 5 вкладками.Каждая вкладка содержит ScrollViewer, Grid и несколько UserControls (MVC) в пределах Grid.

Xaml моего главного окна:

<Window x:Class="CharacterSheetGenerator.View.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:ctrl="clr-namespace:CharacterSheetGenerator.Control"
    xmlns:help="clr-namespace:CharacterSheetGenerator.Helpers"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    mc:Ignorable="d"
    Title="MainWindow" Height="1600" Width="1320" Loaded="Window_Loaded">
<Grid Name="MainGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="40"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top">
        <Button Name="SaveButton" Command="{Binding LoadCommand}" Width="40" Height="30">
            <Image Source="/images/LoadButtonPicture.png"/>
        </Button>
        <Button Name="LoadButton" Command="{Binding SaveCommand}" Width="40" Height="30">
            <Image Source="/images/SaveButtonpicture.png" />
        </Button>
        <!-- Print Button currently in xaml.cs of my MainWindow -->
        <Button Name="Print Button" Click="Button3_Click" Width="40" Height="30">
            <Image Source="/images/PrintButtonPicture.png"/>
        </Button>
    </StackPanel>
    <TabControl Grid.Row="1">
        <TabItem Width="75" Height="20" Header="Übersicht">
            <ScrollViewer HorizontalScrollBarVisibility="Disabled" >
                <i:Interaction.Behaviors>
                    <help:BubbleScrollEvent />
                </i:Interaction.Behaviors>
                <!-- Grid I'd like to print -->
                <Grid Name="Übersicht">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="30"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="30"/>
                </Grid.ColumnDefinitions>
                <Grid Grid.Column="1">
                    <Grid.RowDefinitions>
                    <RowDefinition Height="20"/>
                    <RowDefinition Height="180"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <StackPanel Orientation="Horizontal" Grid.Row="1">
                    <StackPanel>
                        <TextBlock FontSize="34" FontWeight="Bold" Text="Heldendokument"/>
                        <TextBlock FontSize="20" Text="Persönliche Daten" TextAlignment="Center"/>
                    </StackPanel>
                        <ctrl:CharacterAttributes VerticalAlignment="Top" AttributeList="{Binding Attributes, Mode=TwoWay}"/>
                </StackPanel>

                            <Grid Grid.Row="2">
                                <StackPanel>
                                <ctrl:CharacterOverview VerticalAlignment="Top" CharacterInformation="{Binding CharacterInformation}" StatusValues="{Binding StatusValues, Mode=TwoWay}" Traits="{Binding Traits, Mode=TwoWay}" Expirience="{Binding Expirience}" TraitClickCommand="{Binding OpenTraitViewCommand}"/>
                                </StackPanel>
                            </Grid>
                        </Grid>

            </Grid>
            </ScrollViewer>
        </TabItem>
        <TabItem Width="75" Height="20" Header="Fertigkeiten">
            <ScrollViewer HorizontalScrollBarVisibility="Disabled">
                <i:Interaction.Behaviors>
                    <help:BubbleScrollEvent />
                </i:Interaction.Behaviors>
                    <!-- Second Grid I'd like to print -->
                <Grid Name="Fertigkeiten">
                    <!-- [...] -->
        </TabItem>
        <!-- [...] -->

Пример моегоПервая вкладка:

First Tab

Я пометил каждый из своих пользовательских элементов управления несколькими красными полями.

Задача

Голубая пунктирная линия представляет область, которая была бы напечатана на странице DinA4, если бы я просто использовал PrintDialog.PrintVisual(Übersicht, "Printing Übersicht") Я реализовал код из этого ответа и изменил его, чтобы печатать все, а нетолько одна вкладка, но я столкнулся с несколькими проблемами.

Модифицированный код:

   //I tried to create an array and iterate through it
     System.Windows.FrameworkElement[] elements = { Übersicht as System.Windows.FrameworkElement, Fertigkeiten as System.Windows.FrameworkElement, Kampf as System.Windows.FrameworkElement,
                                                       Zauber as System.Windows.FrameworkElement, Inventar as System.Windows.FrameworkElement,};

        PrintDialog printDialog = new PrintDialog();
        if (printDialog.ShowDialog() == true)
        {

            foreach (FrameworkElement e in elements)
            {

                //store original scale
                Transform originalScale = e.LayoutTransform;
                //get selected printer capabilities
                System.Printing.PrintCapabilities capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);


                //get scale of the print wrt to screen of WPF visual
                double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / 1281, capabilities.PageImageableArea.ExtentHeight /
                               1800); // I had to change ActualWidth and Height to static Values, as Grids in Tabs, which haven't been opened at least once since the start of the application had no actual size

                //Transform the Visual to scale
                e.LayoutTransform = new ScaleTransform(scale, scale);

                //get the size of the printer page
                System.Windows.Size sz = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);

                //update the layout of the visual to the printer page size.
                e.Measure(sz);
                e.Arrange(new System.Windows.Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));

                //now print the visual to printer to fit on the one page.
                printDialog.PrintVisual(e, "My Print");

                //apply the original transform.
                e.LayoutTransform = originalScale;

            }

        }

Теперь есть несколько проблем с этим:

  • Все UserControls, которые не были загружены с тех порзапуск приложения будет emtpy (Моя вторая страница имеет DataGrid. Строки все еще там, но все значения отсутствуют)

  • Если вкладка была открыта, но нене текущий открытый, пользовательские элементы управления имеют свои данные, но не меняются соответствующим образом (та же проблема с голубыми точками)

позвольте мне показать вам примерМоя вторая вкладка: (это отсканированные страницы DinA4)

Первая проблема: (вы можете увидеть, что UserControl с цветными полями все еще работает, потому что он уже загружен на первой странице)

enter image description here

Второй выпуск:

enter image description here

Все еще не хватает некоторого кода?Перейдите на мой GitHub и клонируйте проект, чтобы попробовать его сами.

Вопросы:

  • Чтовызывает это, возможно, странное поведение, как я могу его решить?
  • Есть ли другой способ, кроме printDialog.PrintVisual (), чтобы напечатать мои страницы?
...