質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

1回答

689閲覧

DataGridの印刷をしたい

PPP_P

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2023/04/20 00:23

実現したいこと

DataGridの要素を印刷したい。
今画面に映りきらなくてスクロールしなくては見れない部分も2枚目以降に印刷をしたい。

前提

下記のソースコードでアプリケーションの画面の印刷を試しましたが今描画できている範囲1枚分の印刷しかできなく、画面サイズを縮小などをするとそもそも印刷物も縮小されてしまっています。
そこで今の描画に関係なくDataGridの内容を印刷したいと考えていますがそのコードがわかりませんでした。

初心者で見当違いのことを言っているかもしれませんがご教示頂けたら幸いです。よろしくお願いします。

該当のソースコード

C♯

1ソースコード

//画面を印刷
private void Print_Clicked(object sender, RoutedEventArgs e)
{

// PrintDialogを表示する PrintDialog printDialog = new PrintDialog(); if (printDialog.ShowDialog() == true) { // データグリッドをマージンなしで配置 DataGrid dataGrid = this.dgList; Thickness originalMargin = dataGrid.Margin; dataGrid.Padding = new Thickness(30); // 例えば左右上下に10ポイントの余白を追 double scale = 0.55; // 55% 縮小 dataGrid.LayoutTransform = new ScaleTransform(scale, scale); dataGrid.UpdateLayout(); dataGrid.Margin = new Thickness(0); // PrintTicketを作成し、Orientationを設定する PrintTicket printTicket = printDialog.PrintTicket; printTicket.PageOrientation = PageOrientation.Landscape; printDialog.PrintTicket = printTicket; // 印刷可能領域から余白を引いたサイズで測定、配置 double dpi = 96.0; // プリンターのDPI(印刷解像度) System.Windows.Size pageSize = new System.Windows.Size(printDialog.PrintableAreaWidth / dpi * 2.54 - dataGrid.Margin.Left - dataGrid.Margin.Right, printDialog.PrintableAreaHeight / dpi * 2.54 - dataGrid.Margin.Top - dataGrid.Margin.Bottom); dataGrid.Measure(pageSize); double printableWidth = printDialog.PrintableAreaWidth / dpi * 2.54; // cmに変換 double printableHeight = printDialog.PrintableAreaHeight / dpi * 2.54; // cmに変換 double offsetX = (printDialog.PrintableAreaWidth - printableWidth * dpi / 2.54) / 2.0; double offsetY = (printDialog.PrintableAreaHeight - printableHeight * dpi / 2.54) / 2.0; offsetX += dataGrid.Margin.Left; offsetY += dataGrid.Margin.Top; dataGrid.Arrange(new Rect(offsetX, offsetY, pageSize.Width, pageSize.Height)); dataGrid.UpdateLayout(); // データグリッドを印刷する printDialog.PrintVisual(dataGrid, Title); } }

画面上で印刷ボタンをクリックした時にこれを呼び出して印刷をします。
dgListは印刷するDataGrid名です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/04/20 02:27

print wpf whole datagrid をキーワードにググるといろいろヒットしますが、そういうことは調べて、実際にやってみた上での質問でしょうか? 開発環境を質問欄を編集して追記してください。(例: Windows 10 の Visual Studio 2022 で WPF アプリをターゲットフレームワーク .NET Framework 4.8 で作っています・・・とか)
guest

回答1

0

今画面に映りきらなくてスクロールしなくては見れない部分も2枚目以降に印刷をしたい。

DataGridのまま?印刷する方針ということでいいんですかね?

下記のソースコードでアプリケーションの画面の印刷を試しましたが今描画できている範囲1枚分の印刷しかできなく、画面サイズを縮小などをするとそもそも印刷物も縮小されてしまっています。

横が収まるように、わざとScaleTransformをしているのではないのですか?

xamlがわかりませんが、Canvasにでも置かない限りWindowより大きくなりません。
VisualTreeを切ったうえで、MeasureArrangeする必要があります。

.NET7です^^

xml

1<Window 2 x:Class="Q46pp5pq6ad51mb.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <DockPanel x:Name="panel"> 8 <Button 9 Click="Print_Clicked" 10 Content="Print" 11 DockPanel.Dock="Bottom" /> 12 <DataGrid x:Name="dgList" /> 13 </DockPanel> 14</Window>

cs

1using System; 2using System.Collections.Generic; 3using System.Data; 4using System.Linq; 5using System.Printing; 6using System.Windows; 7using System.Windows.Controls; 8using System.Windows.Media; 9using System.Windows.Xps; 10 11namespace Q46pp5pq6ad51mb; 12 13public partial class MainWindow : Window 14{ 15 public MainWindow() 16 { 17 InitializeComponent(); 18 19 var table = new DataTable(); // DataTableを使った深い意味はない(ダミーデータを作るのが楽ってだけ) 20 var columns = Enumerable.Range(1, 6) 21 .Select(x => new DataColumn($"Column{x}")) 22 .ToArray(); 23 table.Columns.AddRange(columns); 24 25 for (var i = 1; i <= 100; i++) 26 { 27 var row = Enumerable.Range(1, table.Columns.Count) 28 .Select(x => $"Row{i}, Column{x}") 29 .ToArray(); 30 table.Rows.Add(row); 31 } 32 33 dgList.ItemsSource = table.AsDataView(); 34 } 35 36 private void Print_Clicked(object sender, RoutedEventArgs e) 37 { 38 var printDialog = new PrintDialog(); 39 if (printDialog.ShowDialog() != true) return; 40 41 var dataGrid = dgList; 42 panel.Children.Remove(dataGrid); // VisualTree切断 43 44 var cc = new ContentControl // なんでもいいのだがPaddingがつけれるので 45 { 46 Padding = new Thickness(30), 47 Content = dataGrid, 48 }; 49 50 var pageSize = new Size(printDialog.PrintableAreaHeight, printDialog.PrintableAreaWidth); // Landscape 51 cc.Measure(pageSize); 52 cc.Arrange(new Rect(pageSize)); 53 54 //printDialog.PrintVisual(dataGrid, Title); 55 56 var printTicket = printDialog.PrintTicket; 57 printTicket.PageOrientation = PageOrientation.Landscape; 58 printDialog.PrintTicket = printTicket; 59 60 61 var writer = PrintQueue.CreateXpsDocumentWriter(printDialog.PrintQueue); 62 var doc = (VisualsToXpsDocument)writer.CreateVisualsCollator(); 63 var sv = dataGrid.Descendants<ScrollViewer>().First(); 64 sv.ScrollToTop(); 65 66 doc.Write(dataGrid); 67 while (sv.VerticalOffset < sv.ScrollableHeight) 68 { 69 sv.PageDown(); 70 dataGrid.UpdateLayout(); 71 doc.Write(dataGrid); 72 }; 73 doc.EndBatchWrite(); 74 75 76 cc.Content = null; 77 panel.Children.Add(dataGrid); // VisualTree復帰 78 } 79} 80 81 82// [VisualTreeの子孫要素を取得する - xin9le.net](https://blog.xin9le.net/entry/2013/10/29/222336) 83public static class DependencyObjectExtensions 84{ 85 public static IEnumerable<DependencyObject> Children(this DependencyObject obj) 86 { 87 if (obj == null) throw new ArgumentNullException(nameof(obj)); 88 var count = VisualTreeHelper.GetChildrenCount(obj); 89 if (count == 0) yield break; 90 for (var i = 0; i < count; i++) 91 { 92 var child = VisualTreeHelper.GetChild(obj, i); 93 if (child != null) yield return child; 94 } 95 } 96 public static IEnumerable<DependencyObject> Descendants(this DependencyObject obj) 97 { 98 if (obj == null) throw new ArgumentNullException(nameof(obj)); 99 foreach (var child in obj.Children()) 100 { 101 yield return child; 102 foreach (var grandChild in child.Descendants()) 103 yield return grandChild; 104 } 105 } 106 public static IEnumerable<T> Children<T>(this DependencyObject obj) where T : DependencyObject => obj.Children().OfType<T>(); 107 public static IEnumerable<T> Descendants<T>(this DependencyObject obj) where T : DependencyObject => obj.Descendants().OfType<T>(); 108}

VisualsToXpsDocument クラス (System.Windows.Xps) | Microsoft Learn

VisualTreeの子孫要素を取得する - xin9le.net

注意点

  • 仮想プリンタで試したので何か根本的に間違っているかも^^;
  • VisualTreeを切る都合上いったん消えてしまう(VisualBrushかなんかでダミーを出しておく?)
  • 最後のページに行がダブる

実際のところ皆さんどうしてるんですかね?

  • プロ(ギョーミーなアプリ)は有償コンポーネント
  • アマ(趣味のアプリ)はファイルに出して「Excelでも何でも好きに印刷してくれ」

って感じでしょうか(私はアマなうえ、印刷したいと思ったこともないです^^;

投稿2023/04/20 13:02

TN8001

総合スコア9326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問