DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ページ設定ダイアログのMarginsが正常に機能しない

ページ設定ダイアログを表示して印刷する方法は「ページ設定ダイアログを表示して印刷する」で紹介しました。このようにPageSetupDialogクラスを使ってページ設定ダイアログを表示したとき、マージン(余白)指定が正常に機能しないという問題があります。

例えば次のようなコードでマージンの上下左右に1インチを指定しても、ページ設定ダイアログでは10ミリと表示されます。さらに、このままOKボタンを押して確定後、PageSetupDialogオブジェクトのPageSettings.Marginsの値を確認すると、上下左右がすべて39になってしまいます。

VB.NET
コードを隠すコードを選択
Dim PageSetupDialog1 As New PageSetupDialog()
PageSetupDialog1.Document = New System.Drawing.Printing.PrintDocument()
'マージンを指定する(上下左右1インチに設定する)
PageSetupDialog1.PageSettings.Margins = _
    New System.Drawing.Printing.Margins(100, 100, 100, 100)

'ページ設定ダイアログを表示する
If PageSetupDialog1.ShowDialog() = DialogResult.OK Then
    '指定されたマージンを表示する
    Console.WriteLine(PageSetupDialog1.PageSettings.Margins)
    '「[Margins Left=39 Right=39 Top=39 Bottom=39]」と表示される
End If
C#
コードを隠すコードを選択
PageSetupDialog PageSetupDialog1 = new PageSetupDialog();
PageSetupDialog1.Document =
    new System.Drawing.Printing.PrintDocument();
//マージンを指定する(上下左右1インチに設定する)
PageSetupDialog1.PageSettings.Margins =
    new System.Drawing.Printing.Margins(100, 100, 100, 100);

//ページ設定ダイアログを表示する
if (PageSetupDialog1.ShowDialog() == DialogResult.OK)
{
    //指定されたマージンを表示する
    Console.WriteLine(PageSetupDialog1.PageSettings.Margins);
    //「[Margins Left=39 Right=39 Top=39 Bottom=39]」と表示される
}

これは.NET Frameworkのバグです。マイクロソフトサポート技術情報814355「BUG:PageSetupDialog が表示される度、余白の値が減少します。」で紹介されています。

.NET Framework 2.0以降

.NET Framework 2.0以降では、解決法が用意されています。それは、PageSetupDialog.EnableMetricプロパティをTrueにすることです。

PageSetupDialog.EnableMetricプロパティをTrueにして上記と同じことを行うと、ページ設定ダイアログで余白が25.4ミリと表示されるようになり、このままOKで確定すると、PageSettings.Marginsの値は100に戻ります。

VB.NET
コードを隠すコードを選択
Dim PageSetupDialog1 As New PageSetupDialog()
'インチとミリメートルの変換が正常に行われるようにする
PageSetupDialog1.EnableMetric = True
PageSetupDialog1.Document = New System.Drawing.Printing.PrintDocument()
'マージンを指定する(上下左右1インチに設定する)
PageSetupDialog1.PageSettings.Margins = _
    New System.Drawing.Printing.Margins(100, 100, 100, 100)

'ページ設定ダイアログを表示する
If PageSetupDialog1.ShowDialog() = DialogResult.OK Then
    '指定されたマージンを表示する
    '「[Margins Left=100 Right=100 Top=100 Bottom=100]」と表示される
    Console.WriteLine(PageSetupDialog1.PageSettings.Margins)
End If
C#
コードを隠すコードを選択
PageSetupDialog PageSetupDialog1 = new PageSetupDialog();
//インチとミリメートルの変換が正常に行われるようにする
PageSetupDialog1.EnableMetric = true;
PageSetupDialog1.Document =
    new System.Drawing.Printing.PrintDocument();
//マージンを指定する(上下左右1インチに設定する)
PageSetupDialog1.PageSettings.Margins =
    new System.Drawing.Printing.Margins(100, 100, 100, 100);

//ページ設定ダイアログを表示する
if (PageSetupDialog1.ShowDialog() == DialogResult.OK)
{
    //指定されたマージンを表示する
    Console.WriteLine(PageSetupDialog1.PageSettings.Margins);
    //「[Margins Left=100 Right=100 Top=100 Bottom=100]」と表示される
}

.NET Framework 1.1以前

.NET Framework 1.1以前の回避法としては、システムでメートル法が選択されているか確認し、そうであればページ設定ダイアログを表示する前にマージンの単位を変更するという方法が考えられます。この方法はニュースグループで紹介されています。

この方法を使って問題を回避したコードの例を示します。

VB.NET
コードを隠すコードを選択
Dim PageSetupDialog1 As New PageSetupDialog
PageSetupDialog1.Document = New System.Drawing.Printing.PrintDocument
'マージンを指定する
PageSetupDialog1.PageSettings.Margins = _
    New System.Drawing.Printing.Margins(100, 100, 100, 100)

'メートル法を使っている時は、メートルに直す
If System.Globalization.RegionInfo.CurrentRegion.IsMetric Then
    PageSetupDialog1.PageSettings.Margins.Top *= 2.54
    PageSetupDialog1.PageSettings.Margins.Bottom *= 2.54
    PageSetupDialog1.PageSettings.Margins.Left *= 2.54
    PageSetupDialog1.PageSettings.Margins.Right *= 2.54
End If

'ページ設定ダイアログを表示する
If PageSetupDialog1.ShowDialog() = DialogResult.OK Then
    Console.WriteLine(PageSetupDialog1.PageSettings.Margins)
ElseIf System.Globalization.RegionInfo.CurrentRegion.IsMetric Then
    'また元に戻す
    PageSetupDialog1.PageSettings.Margins.Top /= 2.54
    PageSetupDialog1.PageSettings.Margins.Bottom /= 2.54
    PageSetupDialog1.PageSettings.Margins.Left /= 2.54
    PageSetupDialog1.PageSettings.Margins.Right /= 2.54
End If
C#
コードを隠すコードを選択
PageSetupDialog PageSetupDialog1 = new PageSetupDialog();
PageSetupDialog1.Document =
    new System.Drawing.Printing.PrintDocument();
//マージンを指定する
PageSetupDialog1.PageSettings.Margins =
    new System.Drawing.Printing.Margins(100, 100, 100, 100);

//メートル法を使っている時は、メートルに直す
if (System.Globalization.RegionInfo.CurrentRegion.IsMetric)
{
    PageSetupDialog1.PageSettings.Margins.Top =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Top * 2.54);
    PageSetupDialog1.PageSettings.Margins.Bottom =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Bottom * 2.54);
    PageSetupDialog1.PageSettings.Margins.Left =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Left * 2.54);
    PageSetupDialog1.PageSettings.Margins.Right =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Right * 2.54);
}

//ページ設定ダイアログを表示する
if (PageSetupDialog1.ShowDialog() == DialogResult.OK)
    //指定されたマージンを表示する
    Console.WriteLine(PageSetupDialog1.PageSettings.Margins);
else if (System.Globalization.RegionInfo.CurrentRegion.IsMetric)
{
    //また元に戻す
    PageSetupDialog1.PageSettings.Margins.Top =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Top / 2.54);
    PageSetupDialog1.PageSettings.Margins.Bottom =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Bottom / 2.54);
    PageSetupDialog1.PageSettings.Margins.Left =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Left / 2.54);
    PageSetupDialog1.PageSettings.Margins.Right =
        (int)Math.Round(
        PageSetupDialog1.PageSettings.Margins.Right / 2.54);
}
  • 履歴:
  • 2007/1/25 .NET Framework 2.0に関する記述を追加。
  • 2011/7/18 PageSetupDialog.EnableMetricプロパティの説明を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。