简体   繁体   中英

How to print the contents of a TextBox

How do I print the contents of a TextBox in metro apps? I have read this quickstart guide on MSDN and many online tutorials, but they are very complicated and do not work with TextBox controls, only RichTextBox controls .

How do we print from a TextBox control in a metro app? Is it even possible? How?

UPDATE 1

I have created a helper class which simplifies printing text box content. You can add helper class via NuGet . If you want to enhance my existing helper class, fork on GitHub


Here I am giving you the modified print sample from MSDN. I have put textbox you can write anything and that will be printed. Please note I have not done sample which prints textbox text exactly same as it is ie formatting (bold, italic, underline, colors). I have set hard-coded print format. You can make your own format.

Stack Overflow has character limit in answer and my code is too long so posting CodePaste.net links.

XAML : http://codepaste.net/9nf261

CS : http://codepaste.net/q3hsm3

Please note that I have used some images so put images in "Images" folder

I just created a small winforms-application with a textbox (textBox1) and a button (button1). The code-behind looks like:

public partial class Form1 : Form
{
    public Form1()
    {
           InitializeComponent();
    }

    private void PrintDocumentOnPrintPage(object sender, PrintPageEventArgs e)
    {
        e.Graphics.DrawString(this.textBox1.Text, this.textBox1.Font, Brushes.Black, 10, 25);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        PrintDocument printDocument = new PrintDocument();
        printDocument.PrintPage += PrintDocumentOnPrintPage;
        printDocument.Print();
    }
}

On a click on the button the printing will be done.

I urge you to check my question here in which I illustrate one of the simplest cases in which you can print something off a page (and you can add that code onto any page you currently have - just replace the example text box's text I use to whatever your heart desires). The reason why they use the rich text boxes is because it can detect when text overflows off the page, thus they use that information to create a new page with another rich text box until no more overflowing occurs. No matter, you can use your own string parser to split your text up on different pages. Essentially, printing in Windows 8 apps will print any UIElement you want, so you can pretty much XAML align your page programmatically and style it just the way you'd style any other Windows app. Seriously, check the question, it'll be a huge help. I spent hours hacking the PrintSample down to the simplest case until I figured out how it all worked. No point in reinventing the wheel, use my struggles to your advantage, that's what Stack is all about. Cheers!

Edit: I'll pose the code here for your convenience, guys.

Step 1: Add this code to the page with your text box.

        protected PrintDocument printDocument = null;
        protected IPrintDocumentSource printDocumentSource = null;
        internal List<UIElement> printPreviewElements = new List<UIElement>();
        protected event EventHandler pagesCreated;

        protected void PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs e)
        {
            PrintTask printTask = null;
            printTask = e.Request.CreatePrintTask("C# Printing SDK Sample", sourceRequested =>
            {
                printTask.Completed += async (s, args) =>
                {
                    if (args.Completion == PrintTaskCompletion.Failed)
                    {
                        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
                        {
                            MessageDialog dialog = new MessageDialog("Something went wrong while trying to print. Please try again.");
                            await dialog.ShowAsync();
                        });
                    }
                };
                sourceRequested.SetSource(printDocumentSource);
            });
        }

        protected void RegisterForPrinting()
        {
            printDocument = new PrintDocument();
            printDocumentSource = printDocument.DocumentSource;
            printDocument.Paginate += CreatePrintPreviewPages;
            printDocument.GetPreviewPage += GetPrintPreviewPage;
            printDocument.AddPages += AddPrintPages;
            PrintManager printMan = PrintManager.GetForCurrentView();
            printMan.PrintTaskRequested += PrintTaskRequested;
        }

        protected void UnregisterForPrinting()
        {
            if (printDocument != null)
            {
                printDocument.Paginate -= CreatePrintPreviewPages;
                printDocument.GetPreviewPage -= GetPrintPreviewPage;
                printDocument.AddPages -= AddPrintPages;
                PrintManager printMan = PrintManager.GetForCurrentView();
                printMan.PrintTaskRequested -= PrintTaskRequested;
            }
        }

        protected void CreatePrintPreviewPages(object sender, PaginateEventArgs e)
        {
            printPreviewElements.Clear();
            PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);
            PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);
            AddOnePrintPreviewPage(pageDescription);
            if (pagesCreated != null)
            {
                pagesCreated.Invoke(printPreviewElements, null);
            }
            ((PrintDocument)sender).SetPreviewPageCount(printPreviewElements.Count, PreviewPageCountType.Intermediate);
        }

        protected void GetPrintPreviewPage(object sender, GetPreviewPageEventArgs e)
        {
            ((PrintDocument)sender).SetPreviewPage(e.PageNumber, printPreviewElements[e.PageNumber - 1]);
        }

        protected void AddPrintPages(object sender, AddPagesEventArgs e)
        {
            foreach (UIElement element in printPreviewElements)
            {
                printDocument.AddPage(element);
            }
            ((PrintDocument)sender).AddPagesComplete();
        }

        protected void AddOnePrintPreviewPage(PrintPageDescription printPageDescription)
        {
            TextBlock block = new TextBlock();
            block.Text = "This is an example.";
            block.Width = printPageDescription.PageSize.Width;
            block.Height = printPageDescription.PageSize.Height;
            printPreviewElements.Add(block);
        }
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            RegisterForPrinting();
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            UnregisterForPrinting();
        }

Step 2: Replace block.Text with your desired text.

Step 3: Use a print button to show the print UI:

        private async void PrintDocument(object sender, RoutedEventArgs e)
        {
            await Windows.Graphics.Printing.PrintManager.ShowPrintUIAsync();
        }

Step 4: Put RequestedTheme="Light" in your App.xaml and you're done. Note: Might be able to alternatively style the textbox the way you want in this XAML class and not have to set the theme of the entire app.

Step 5 (Later On): You might want to consider adding in your own new page detection logic that keeps calling that method up top to create a new page.

Step 6 (Right Now): Get into a fight with the guy at M$ who's responsible for making us struggle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM