3

物理プリンターに送信されたときに ListBox を完全に印刷する次のコードのチャンクを作成しましたが、それを XPS プリンター ドライバーに送信しようとするとき、または XpsDocumentWriter クラスを使用するときに (ボンネットの下で同じコードを使用すると仮定します)、私は次の例外を受け取ります。

System.ArgumentException はユーザー コードによって処理されませんでした Message=Width および Height は負ではない必要があります。Source=ReachFramework StackTrace: System.Windows.Xps.Serialization.VisualSerializer.WriteTileBrush (文字列要素、TileBrush ブラシ、Rect 境界) で

例外は明らかに、アイテムの幅/高さが正しくないことを示していますが、コードを別のプリンター (物理ドライバーと XPS ドライバー) に送信するときにコードをデバッグしましたが、違いを見つけることができませんでした。

以下は、プリンターに送信するビジュアルを作成する方法です。

private ScrollViewer GeneratePrintableView()
    {
        ScrollViewer scrollView = new ScrollViewer();

        Grid grid = new Grid { Background = Brushes.White, Width = this.myListBox.ActualWidth, Height = this.myListBox.ActualHeight };

        grid.RowDefinitions.Add(new RowDefinition());
        grid.RowDefinitions[0].Height = new GridLength(0, GridUnitType.Auto);
        grid.RowDefinitions.Add(new RowDefinition());
        grid.RowDefinitions[1].Height = new GridLength(0, GridUnitType.Auto);

        // Add the title and icon to the top
        VisualBrush titleClone = new VisualBrush(this.TitleBar);
        var titleRectangle = new Rectangle { Fill = titleClone, Width = this.TitleBar.ActualWidth, Height = this.TitleBar.ActualHeight };
        grid.Children.Add(titleRectangle);
        Grid.SetRow(titleRectangle, 0);

        this.myListBox.Width = this.myListBox.ActualWidth;
        this.myListBox.Height = this.myListBox.ActualHeight;

        VisualBrush clone = new VisualBrush(this.myListBox) { Stretch = Stretch.None, AutoLayoutContent = true };
        var rectangle = new Rectangle { Fill = clone, Width = this.myListBox.ActualWidth, Height = this.myListBox.ActualHeight };
        Border border = new Border { Background = Brushes.White, Width = this.myListBox.ActualWidth, Height = this.myListBox.ActualHeight };
        border.Child = rectangle;
        grid.Children.Add(border);
        Grid.SetRow(border, 1);

        scrollView.Width = this.myListBox.ActualWidth;
        scrollView.Height = this.myListBox.ActualHeight;
        scrollView.Content = grid;
        scrollView.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;

        return scrollView;
    }

私の DocumentPaginator 実装での GetPage オーバーライドは次のとおりです。

public override DocumentPage GetPage(int pageNumber)
    {
        Page page = new Page();
        double z = 0.0;

        this.grid = new Grid();
        this.grid.RowDefinitions.Add(new RowDefinition());
        this.grid.RowDefinitions[0].Height = new GridLength(0, GridUnitType.Auto);

        this.grid.Children.Add(this.printViewer);
        Grid.SetRow(this.printViewer, 0);

        //Adjusting the vertical scroll offset depending on the page number
        if (pageNumber + 1 == 1) //if First Page
        {
            this.printViewer.ScrollToVerticalOffset(0);
            this.printViewer.UpdateLayout();
        }
        else if (pageNumber + 1 == _verticalPageCount) //if Last Page
        {
            if (this.printViewer.ScrollableHeight == 0) //If printing only single page and the contents fits only on one page
            {
                this.printViewer.ScrollToVerticalOffset(0);
                this.printViewer.UpdateLayout();

            }
            else if (this.printViewer.ScrollableHeight <= this.printViewer.Height) //If scrollconentheight is less or equal than scrollheight
            {
                this.printViewer.Height = this.printViewer.ScrollableHeight;
                this.printViewer.ScrollToEnd();
                this.printViewer.UpdateLayout();
            }
            else //if the scrollcontentheight is greater than scrollheight then set the scrollviewer height to be the remainder between scrollcontentheight and scrollheight
            {
                this.printViewer.Height = (this.printViewer.ScrollableHeight % this.printViewer.Height) + 5;
                this.printViewer.ScrollToEnd();
                this.printViewer.UpdateLayout();
            }
        }
        else //Other Pages
        {
            z = z + this.printViewer.Height;
            this.printViewer.ScrollToVerticalOffset(z);
            this.printViewer.UpdateLayout();
        }

        page.Content = this.grid; //put the grid into the page
        page.Arrange(new Rect(this.originalMargin.Left, this.originalMargin.Top, this.ContentSize.Width, this.ContentSize.Height));
        page.UpdateLayout();

        return new DocumentPage(page);
    }

興味深いことに、四角形の塗りつぶしをクローンではなくブラシに変更すると、例外は発生せず、出力ファイルは正しいサイズになります。

これが機能しない理由をデバッグしようと 1 日以上費やしました。誰かが同様の問題を見たか、私が犯した間違いを指摘できることを願っています。

返信ありがとうございます。

4

4 に答える 4

1

問題を修正することはできませんでしたが、このリンクWPF ビジュアルのページ付けされた印刷を使用して、WPF アプリケーション内で複雑なビジュアルを印刷できる適切なソリューションを見つけることができました。

于 2014-03-27T14:19:53.223 に答える
1

VisualBrush の作成時に myListBox の ActualWidth と ActualHeight の値を確認しましたか? myListBox がどこから来たのかはわかりませんが、xps ドキュメントを生成するまでにレンダリングされないと、問題が発生する可能性があります。コントロールを手動で強制的にレンダリングして、違いがあるかどうかを確認できます。

于 2012-12-18T16:17:30.410 に答える