【问题标题】:How to print the contents of a TextBox如何打印文本框的内容
【发布时间】:2013-03-11 22:17:06
【问题描述】:

如何在 Metro 应用程序中打印 TextBox 的内容?我已经阅读了this quickstart guide on MSDN 和许多在线教程,但是它们非常复杂并且不适用于 TextBox 控件,只有 RichTextBox 控件

我们如何从 Metro 应用程序中的 TextBox 控件进行打印?甚至可能吗?怎么样?

【问题讨论】:

  • 抱歉,打印复杂的。哪个部分不适用于常规 TextBox?
  • @TwoMore 对不起,不是骗子——这个问题没有答案。它根本不起作用。
  • @CodyGray 确实,打印似乎很复杂。好吧,我在网上看到的所有代码都与 RichTextBox 控件有关,并且整个代码都基于您使用的是 RichTextBox 的事实。当我在这里和那里简单地更改部件时,没有对 RichTextBox 的引用——只有 TextBox,不起作用(如我所料)——这让我问——我们究竟如何用 TextBox 打印?似乎还没有人这样做。
  • 为什么投反对票?这不是重复的。这里的其他问题和答案未能回答我的问题,并且提供的代码是针对 RichTextBox 控件的,并且不起作用。
  • 在 Windows 窗体中做任何不平凡的事情需要的不仅仅是“几行代码”。不过,我承认 Windows 8 的构思和设计都很糟糕。 (另请注意,我不是反对者之一。这是一个完全有效的问题。我只是敦促您提供更多详细信息。)

标签: c# .net windows-8 microsoft-metro windows-store-apps


【解决方案1】:

更新 1

我创建了一个帮助类来简化打印文本框内容。您可以通过NuGet 添加助手类。如果你想增强我现有的帮助类,请在 GitHub 上 fork


我在这里给你来自 MSDN 的modified print sample。我已经放了文本框,你可以写任何东西并且会被打印出来。请注意,我没有完成打印文本框文本的示例,即格式(粗体、斜体、下划线、颜色)。我设置了硬编码的打印格式。您可以制作自己的格式。

Stack Overflow 在回答中有字符限制,我的代码太长,所以发布 CodePaste.net 链接。

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

客服:http://codepaste.net/q3hsm3

请注意,我使用了一些图片,所以将图片放在“Images”文件夹中

【讨论】:

  • 添加代码下载链接不是一个好的答案。如果您将该文件从 skydrive 中取出,则此答案将毫无用处。包括代码作为答案的一部分。
  • 我从不删除我的公开样本。然后我也在这里发布代码
  • @Xyroid 谢谢你这样做。我在网上遇到了 NullReferenceException:`PrintingRoot.Children.Add(page);` 但我不明白为什么任何东西都是空的?
  • 我没有遇到任何问题,我建议您创建新项目并使用我的 Skydrive 代码。我的 Skydrive 项目由我测试。
  • 我认为代码太长而不适合 SO 的事实很好地表明,从 Metro 应用程序中的 TextBox 打印纯文本过于复杂且不必要。
【解决方案2】:

我刚刚创建了一个带有文本框 (textBox1) 和一个按钮 (button1) 的小型 winforms 应用程序。代码隐藏如下:

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();
    }
}

单击按钮即可完成打印。

【讨论】:

  • 问题是关于 Windows 商店应用程序,这是一个完全不同的野兽。
  • 问题是关于 Windows Store 应用程序,它与 Windows Forms 应用程序完全不同。
  • WinForms 中的 4 行代码,而 Metro 应用程序中可能有数百行代码 - 这是为了什么??????只是为了打印 TextBox 的内容,其中可能只有一个字符,也可能没有?微软真的把这个搞砸了。
【解决方案3】:

我敦促您使用check my question here,其中我说明了一种最简单的情况,在这种情况下您可以从页面上打印某些内容(并且您可以将该代码添加到您当前拥有的任何页面上 - 只需替换示例文本框的文本 I随心所欲地使用)。他们使用富文本框的原因是因为它可以检测到文本何时溢出页面,因此他们使用该信息与另一个富文本框创建一个新页面,直到不再发生溢出。无论如何,您可以使用自己的字符串解析器将文本拆分到不同的页面上。本质上,在 Windows 8 应用程序中打印将打印您想要的任何 UIElement,因此您几乎可以通过 XAML 以编程方式对齐您的页面,并按照您为任何其他 Windows 应用程序设置样式的方式来设置它的样式。说真的,检查问题,这将是一个巨大的帮助。我花了几个小时将 PrintSample 破解为最简单的情况,直到我弄清楚它是如何工作的。重新发明轮子没有意义,利用我的努力为您服务,这就是 Stack 的全部意义所在。干杯!

编辑:为了您的方便,我将代码放在这里,伙计们。

第 1 步:将此代码添加到带有文本框的页面。

        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();
        }

第 2 步:将 block.Text 替换为您想要的文本。

第 3 步:使用打印按钮显示打印 UI:

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

第 4 步:将 RequestedTheme="Light" 放入您的 App.xaml 中,您就完成了。注意:也许可以在此 XAML 类中按照您想要的方式设置文本框的样式,而不必设置整个应用程序的主题。

第 5 步(稍后):您可能需要考虑添加自己的新页面检测逻辑,该逻辑会不断调用该方法以创建新页面。

第 6 步(现在):与 M$ 负责让我们陷入困境的人打架。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多