NET環境下有關列印版面設定、印表機設定、預覽列印對話方塊的實現(二)

來源:互聯網
上載者:User
列印|對話方塊|頁面 前篇說了.NET環境下有關列印版面設定、印表機設定、預覽列印對話方塊的實現,現在到了我們應用它們的時候了。

我們需要做下面的一些事情:
1、將上篇中寫的程式輸出類型改為類庫並編譯成PrinterPageSetting.dll;
2、建立C#或VB.net項目,並在項目的引用處添加引用,在彈出的對話方塊的.NET標籤中瀏覽並選擇PrinterPageSetting.dll;
3、在預設視窗Form1上增加一個TextBox文字框控制項,預設名TextBox1(實際項目中建議採用命名及編碼規範,如frmTestPrint,txtPrint)
4、從工具箱中拖一個MainMenu到視窗Form1,建立mainMenu1菜單對象,建立主菜單menuFile
5、單擊menuFile,在其下方輸入處分別建立menuFilePageSetup、menuFilePrintPreview、menuFilePrint菜單。我想大家明白這幾個菜單的意義了,這是命名規範最基本的。

準備工作做完了,看看我們怎麼使用PrinterPageSetting輕鬆完成列印版面設定、印表機設定、預覽列印對話方塊。

第一步:在視窗類別中申明並執行個體化PrinterPageSetting,當然執行個體化對象可以放在建構函式中。
C#:
private GoldPrinter.PrinterPageSetting printerPageSetting = new GoldPrinter.PrinterPageSetting();
VB.net:
Private printerPageSetting As New GoldPrinter.PrinterPageSetting

第二步:寫一個實現列印的具體過程
C#:
private void PrintDocument_PrintPage_Handler(object o,System.Drawing.Printing.PrintPageEventArgs e)
{
System.Drawing.Graphics g = e.Graphics;
if (Draw(g))
{
e.HasMorePages = true; //要分頁列印
}
else
{
e.HasMorePages = false; //列印結束
}
}

VB.net:
Private Sub printDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
Dim g As System.Drawing.Graphics = e.Graphics
If Me.Draw(g) Then
e.HasMorePages = True '要分頁列印
Else
e.HasMorePages = False '列印結束
End If
End Sub

大家可以看到我們是怎麼使程式在列印時自動分頁的,就是設定HasMorePages屬性為真就可以了。為了清晰可見,我將真正列印的具體過程獨立出來用Draw()實現。
在第二步中我們實現列印的具體過程,在PrinterPageSetting類中,我們並不知道列印的具體實現,就設計了PrintPage委託,讓調用者自己實現,然後告訴PrinterPageSetting是用哪一個方法實現,也就是第三步了。

第三步:列印委託
在視窗空白處雙擊,在Form1_Load事件中輸入相關語句。當然也可以放在建構函式中,這裡為了描述的方便。
C#:
private void Form1_Load(object sender, System.EventArgs e)
{
this.printerPageSetting.PrintPage += new GoldPrinter.PrintPageDelegate(PrintDocument_PrintPage_Handler);
}

如果你不知上一句是什麼意思,就用這一句吧:
this.printerPageSetting.PrintPageValue = new GoldPrinter.PrintPageDelegate(PrintDocument_PrintPage_Handler);
意思就是告訴printerPageSetting列印的具體實現過程是PrintDocument_PrintPage_Handler(第二步)

VB.net:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.printerPageSetting.PrintPageValue = New GoldPrinter.PrintPageDelegate(AddressOf printDocument_PrintPage)
End Sub

大家還可以一試啊,
Private WithEvents printDocument As System.Drawing.Printing.PrintDocument '第一步:在申明視窗級變數
Me.printDocument = Me.printerPageSetting.PrintDocument '第二步:在此將兩個量聯絡起來
將printDocument_PrintPage(...)加上 Handles printDocument.PrintPage


第四步:顯示版面設定\印表機設定\預覽列印對話方塊
分別在幾個菜單上單擊,具體代碼如下:

C#:
private void menuFilePageSetup_Click(object sender, System.EventArgs e)
{
this.printerPageSetting.ShowPageSetupDialog(); //顯示版面設定對話方塊
}

private void menuFilePrintPreview_Click(object sender, System.EventArgs e)
{
this.printerPageSetting.ShowPrintPreviewDialog(); //顯示預覽列印對話方塊
}

private void menuFilePrint_Click(object sender, System.EventArgs e)
{
this.printerPageSetting.ShowPrintSetupDialog(); //顯示預覽列印對話方塊
}

VB.net:
Private Sub menuFilePageSetup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuFilePageSetup.Click
Me.printerPageSetting.ShowPageSetupDialog()
End Sub

Private Sub menuFilePrintPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuFilePrintPreview.Click
Me.printerPageSetting.ShowPrintPreviewDialog()
End Sub

Private Sub menuFilePrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuFilePrint.Click
Me.printerPageSetting.ShowPrintSetupDialog()
End Sub

哈哈,到現在為此,我們做的工作基本完成了,不過不要忘了Draw()噢。
C#:
private bool Draw(System.Drawing.Graphics g)
{
g.DrawString("Hello World!",new Font("宋體",15),Brushes.Black,new PointF(0,0));
return false;
}

VB.net:
Private Function Draw(ByVal g As System.Drawing.Graphics) As Boolean
g.DrawString("Hello World!", New Font("宋體", 15), Brushes.Black, New PointF(0, 0))
Return False
End Function

大家可不要笑這個Draw()太簡單喲!運行看看,嘿,程式確實能夠完成列印版面設定、印表機設定、預覽列印對話方塊的功能,還能設定橫向縱向列印,改變紙張大小等設定呢。



擴充:

當然,既然PrintDocument_PrintPage_Handler()與printDocument_PrintPage()組織的清晰且能夠分頁,那我就不讓大家遺憾了。
我現在分別用VB.net和C#實現一個能夠分頁列印的例子,而且上面的工作不白做,僅僅改一下Draw()就可以了。

VB.net:
Private Function Draw(ByVal g As System.Drawing.Graphics) As Boolean
Return DrawText(g, Me.printerPageSetting.PrintDocument, Me.TextBox1.Text)
End Function

'這段代碼改編自MSDN
Private Function DrawText(ByVal g As System.Drawing.Graphics, ByVal pdoc As System.Drawing.Printing.PrintDocument, ByVal text As String) As Boolean
g.DrawString("Hello World!", New Font("宋體", 15), Brushes.Black, New PointF(0, 0))
Return False

Static intCurrentChar As Int32
Dim font As New Font("宋體", 10)

Dim intPrintAreaHeight, intPrintAreaWidth As Int32
With pdoc.DefaultPageSettings
intPrintAreaHeight = .PaperSize.Height - .Margins.Top - .Margins.Bottom
intPrintAreaWidth = .PaperSize.Width - .Margins.Left - .Margins.Right
End With

' 橫向列印,寬與高交換
If pdoc.DefaultPageSettings.Landscape Then
Me.Swap(intPrintAreaWidth, intPrintAreaHeight)
End If

'定義列印範圍
Dim rectPrintingArea As New RectangleF(pdoc.DefaultPageSettings.Margins.Left, pdoc.DefaultPageSettings.Margins.Top, intPrintAreaWidth, intPrintAreaHeight)

Dim fmt As New StringFormat(StringFormatFlags.LineLimit)

Dim intLinesFilled, intCharsFitted As Int32
g.MeasureString(Mid(text, intCurrentChar + 1), font, _
New SizeF(intPrintAreaWidth, intPrintAreaHeight), fmt, _
intCharsFitted, intLinesFilled)

g.DrawString(Mid(text, intCurrentChar + 1), font, _
Brushes.Black, rectPrintingArea, fmt)

intCurrentChar += intCharsFitted

If intCurrentChar < text.Length Then
Return True
Else
intCurrentChar = 0
Return False
End If
End Function

'兩個數的值互換
Private Sub Swap(ByRef i As Int32, ByRef j As Int32)
Dim tmp As Int32 = i
i = j
j = tmp
End Sub

VB.net實現了,那我就換一個物件導向的實現方法吧。

C#:
在C#項目上右鍵選擇添加\添加類,命名為DrawText.cs,這裡列出全部內容:
///
/// 在繪圖表面地區內繪製文本
///
public class DrawText
{
private Graphics _graphics;
private RectangleF _rectangleF;
private string _text;
private Font _font;
private Brush _brush;
private StringFormat _stringFormat;

private int _startChar;
private int _linesFilled;
private int _charsFitted;

#region 欄位屬性
public Graphics Graphics
{
get
{
return _graphics;
}
set
{
_graphics = value;
}
}

public RectangleF RectangleF
{
get
{
return _rectangleF;
}
set
{
_rectangleF = value;
}
}

public string Text
{
get
{
return _text;
}
set
{
_text = value;
}
}

public Font Font
{
get
{
return _font;
}
set
{
if (value != null)
{
_font = value;
}
}
}

public Brush Brush
{
get
{
return _brush;
}
set
{
if (value != null)
{
_brush = value;
}
}
}

public StringFormat StringFormat
{
get
{
return _stringFormat;
}
set
{
_stringFormat = value;
}
}


public int StartChar
{
get
{
return _startChar;
}
set
{
_startChar = value;
if (_startChar < 0)
{
_startChar = 0;
}
}
}

public int CharsFitted
{
get
{
return _charsFitted;
}
}

public int LinesFilled
{
get
{
return _linesFilled;
}
}
#endregion


public DrawText()
{
_text = "";
_font = new Font("宋體",10);
_rectangleF = new RectangleF(0,0,0,_font.Height);
_brush = Brushes.Black;

_startChar = 0;
_linesFilled = 0;
_charsFitted = 0;

_stringFormat = new StringFormat(StringFormatFlags.LineLimit);
}

public DrawText(string text):this()
{
_text = text;
}


public void Draw()
{
if (_graphics != null)
{
int intLinesFilled, intCharsFitted;

_graphics.MeasureString(_text.Substring(_startChar),_font,new SizeF(_rectangleF.Width, _rectangleF.Height),_stringFormat,out intCharsFitted,out intLinesFilled);

_graphics.DrawString(_text.Substring(_startChar),_font,_brush,_rectangleF,_stringFormat);

this._linesFilled = intLinesFilled;
this._charsFitted = intCharsFitted;
}
}


然後將原來的Draw()用下面的語句替換掉:

private static int intCurrentCharIndex;
private bool Draw(System.Drawing.Graphics g)
{
float width,height;
width = this.printerPageSetting.PrintDocument.DefaultPageSettings.PaperSize.Width - this.printerPageSetting.PrintDocument.DefaultPageSettings.Margins.Left - this.printerPageSetting.PrintDocument.DefaultPageSettings.Margins.Right;
height = this.printerPageSetting.PrintDocument.DefaultPageSettings.PaperSize.Height -this.printerPageSetting.PrintDocument.DefaultPageSettings.Margins.Top - this.printerPageSetting.PrintDocument.DefaultPageSettings.Margins.Bottom;
//橫向列印,寬與高交換
if (this.printerPageSetting.PrintDocument.DefaultPageSettings.Landscape)
{
Swap(ref width,ref height);
}

RectangleF recPrintArea = new RectangleF(this.printerPageSetting.PrintDocument.DefaultPageSettings.Margins.Left,this.printerPageSetting.PrintDocument.DefaultPageSettings.Margins.Top,width,height);



DrawText drawText = new DrawText(this.TextBox1.Text);
drawText.Graphics = g;
drawText.RectangleF = recPrintArea;
drawText.StartChar = intCurrentCharIndex;
drawText.Draw();

intCurrentCharIndex += drawText.CharsFitted;

if (intCurrentCharIndex < this.TextBox1.Text.Length)
{
return true;
}
else
{
intCurrentCharIndex = 0;
return false;
}
}

//兩個數的值互換
private void Swap(ref float i,ref float j)
{
float tmp = i;
i = j;
j = tmp;
}

在VB.net和C#的實現中,都分別寫了一個互換兩個數的值Swap()函數,供頁面橫向列印時調用,這裡不再敖述。

還需要補充說明的是在上篇:
開源:.NET環境下有關列印版面設定、印表機設定、預覽列印對話方塊的實現
http://blog.csdn.net/flygoldfish/archive/2004/08/17/77208.aspx
中,我又稍有改動,列表如下:
1、IPrinterPageSetting.cs中將PrintPage改為PrintPageValue,增加event PrintPageDelegate PrintPage;
2、WebPrinterPageSetting.cs中將PrintPage改為PrintPageValue,增加public event GoldPrinter.PrintPageDelegate PrintPage;
3、WinPrinterPageSetting.cs中PrintPage改為PrintPageValue,增加

public event PrintPageDelegate PrintPage
{
add
{
_printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(value);
_printPageValue = value;
}
remove
{
_printDocument.PrintPage -= new System.Drawing.Printing.PrintPageEventHandler(value);
_printPageValue = null;
}
}
4、PrinterPageSetting.cs中PrintPage改為PrintPageValue,增加
public event PrintPageDelegate PrintPage
{
add
{
_printerPageSetting.PrintPage += new PrintPageDelegate(value);
}
remove
{
_printerPageSetting.PrintPage -= new PrintPageDelegate(value);
}
}

5、PrinterPageSetting.cs中將PrinterPageSetting的有參建構函式public PrinterPageSetting(PrintDocument printDocument)
的_printerPageSetting.PrintDocument = printDocument;加一個判斷,即
if (printDocument != null)
{
_printerPageSetting.PrintDocument = printDocument;
}
這樣,系統會提供一個預設的PrintDocument對象。





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.