Hi,
First of all let me confess that I could not get the solution to the same problem from an earlier post Printing :by Mr.Richard MSL (dated September 24th 2006) working.
(Replied by Mr.Walter Wang - September 27th 2006)
My problem is to Print a text from a RichTextBox with all options like - AllowMultiplePages enabled plus PrintPreview and PageSetup.
I tried 2 algorithms - 1 posted in Microsoft and 1 posted in this forum.
Everything works brilliantly when i extend the RichTextBox as specified in :
http://support.microsoft.com/kb/812425/
(How to print the content of a RichTextBox control by using Visual C# .NET or Visual C# 2005). In this case it is difficult to provide options while printing.
In the post that i found here, I have copy pasted the same below, I am unable to print it correctly with print preview. If i can get any of the 2 algorithms working then that solves my problem.
For the post the follows below - if i can get the working project then it would be very helpful. Also please tell me how and where to download the attachment as i am new to this.
My deadline is today as i am working on this from 2 days. Thanks in advance
.
Richard MSL
Guest
n/a Posts
September 27th, 2006
04:05 PM
#4
Re: Printing
Thanks Walter, that is very helpful, just what I was looking for. Thanks.
"Walter Wang [MSFT]" wrote:
Quote:
Originally Posted by
Hi,
>
In WinForm's printing architecture, it's the user's responsibility to do
the pagination:
>
1) System fires the event PrintPage
2) User process the event, prints content to the Graphics object; at the
end of the event, user need to set the flag PrintPageEventArgs.HasMorePages
to notify the system whether or not there're remaining pages.
3) System checks the flag, if it's True, go to step 1).
>
If user wants to print some pages, the settings are returned in the
PrinterSettings.PrintRange, FromPage, ToPage, etc. But they have nothing to
do with how the PrintPage event is raised and handled. That's why you need
to save the FromPage and ToPage as member variables and use them in the
event later.
>
From your code, I assume what you're doing is to print a multi-page text
file like following example:
>
[1] How to: Print a Multi-Page Text File in Windows Forms
http://msdn2.microsoft.com/en-us/library/cwbe712d.aspx
>
However, the example above doesn't allow user selectively print some pages
using AllowSomePages property.
>
Let's implement this feature now.
>
First, to let user know exactly the total pages count, we need to create a
custom PrintController which computes the page count dynamically.
>
class PageCountPrintController : PreviewPrintController
{
int pageCount = 0;
>
public override void OnStartPrint(PrintDocument document,
PrintEventArgs e)
{
base.OnStartPrint(document, e);
this.pageCount = 0;
}
>
public override System.Drawing.Graphics OnStartPage(PrintDocument
document, PrintPageEventArgs e)
{
// Increment page count
++this.pageCount;
return base.OnStartPage(document, e);
}
>
public int PageCount
{
get { return this.pageCount; }
}
>
// Helper method to simplify client code
public static int GetPageCount(PrintDocument document)
{
// Must have a print document to generate page count
if (document == null)
throw new ArgumentNullException("PrintDocument must be
set.");
>
// Substitute this PrintController to cause a Print to initiate
the
// count, which means that OnStartPrint and OnStartPage are
called
// as the PrintDocument prints
PrintController existingController = document.PrintController;
PageCountPrintController controller = new
PageCountPrintController();
document.PrintController = controller;
document.Print();
document.PrintController = existingController;
return controller.PageCount;
}
}
>
Also, we can use this "pre-processing" phase to get which text should be
printed on which page.
>
void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
>
if (_isPreProcessing)
{
int charactersOnPage = 0;
int linesPerPage = 0;
// Sets the value of charactersOnPage to the number of
characters
// of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(_stringToPrint, this.Font,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);
>
// Save the text for the page
_pages.Add(_stringToPrint.Substring(0, charactersOnPage));
// Remove the portion of the string that has been printed.
_stringToPrint = _stringToPrint.Substring(charactersOnPage);
>
// Check to see if more pages are to be printed.
e.HasMorePages = (_stringToPrint.Length 0);
if (!e.HasMorePages) _stringToPrint = null;
}
else
{
// Draws the string within the bounds of the page
e.Graphics.DrawString(_pages[_pageNumber-1], this.Font,
Brushes.Black,
e.MarginBounds, StringFormat.GenericTypographic);
_pageNumber++;
e.HasMorePages = _pageNumber <= _maxPageNumber;
if (!e.HasMorePages) _pages = null;
}
}
>
private void button1_Click(object sender, EventArgs e)
{
ReadFile();
>
// Get the total page count
_isPreProcessing = true;
_pages = new List<string>();
_totalPages =
PageCountPrintController.GetPageCount(_printDocume nt1);
_isPreProcessing = false;
>
_printDocument1.PrinterSettings.FromPage = 1;
_printDocument1.PrinterSettings.ToPage = _totalPages;
_printDocument1.PrinterSettings.MinimumPage = 1;
_printDocument1.PrinterSettings.MaximumPage = _totalPages;
PrintDialog pd = new PrintDialog();
pd.AllowSomePages = true;
pd.Document = _printDocument1;
if (pd.ShowDialog() == DialogResult.OK)
{
if (pd.PrinterSettings.PrintRange == PrintRange.SomePages)
{
_pageNumber = _printDocument1.PrinterSettings.FromPage;
_maxPageNumber = _printDocument1.PrinterSettings.ToPage;
}
else
{
_pageNumber = 1;
_maxPageNumber = _totalPages;
}
_printDocument1.Print();
}
}
>
>
I've created a complete working project for you to test it. It will print
"c:\testpage.txt". You can use the "Page Setup..." button to change the
margins and you will notice the total page count changes accordingly when
you click "Print..." to bring up the print dialog.
>
Note: you will have to use Outlook Express to download the attachment