从WPF打印

时间:2013-02-22 05:36:18

标签: c# wpf xaml printdialog

我有一个WPF数据输入屏幕/窗口,我想提供打印输出。 (确切地说,它是一个UserControl,我已经装配好像我想要打印的TabControl中的TabItem一样工作。)

为了打印得很好,我做了几个布局转换,将窗口缩放到纸张大小,并更改应用程序的外观。 'print skin'将背景更改为白色,并删除标题标签等背景。

这非常有效 - 我有MessageBox.Show()提示告诉我发生了什么。

然而,当我拿出Messagebox.Show提示时,我发现我的所有打印魔法都不起作用,就好像enire打印方法只是:UserControl上的PrintVisual();。 (我把它缩小到一个MessageBox,我不能在不破坏的情况下摆脱它。)

代码(对不起,我已经添加了批量评论):

private void PrintStatements()
{
  PrintDialog print = new PrintDialog();

  /// Needed data
  PrintCapabilities capabilities = print.PrintQueue.GetPrintCapabilities(print.PrintTicket);
  double pageMargin = 1 / 2.54;   // 1cm
  double pageWidth = capabilities.PageImageableArea.ExtentWidth - (pageMargin);
  double pageLength = capabilities.PageImageableArea.ExtentHeight - (pageMargin);
  Size pageSize = new Size(pageWidth, pageLength);
  ResourceDictionary resources = new ResourceDictionary();

  bool canPrint = print.ShowDialog() ?? false;
  if (canPrint)
  {
    double tabWidth = StatementsTabCtrl.ActualWidth;
    double tabHeight = StatementsTabCtrl.ActualHeight;

    /// 1.  Get tab item content ('currentTabContent') 
    StatementsTabItem currentTabContent = StatementsTabCtrl.SelectedContent as StatementsTabItem;

    /// 2.  Get Original Specs of currentTabContent
    ResourceDictionary origSkin = Application.Current.Resources;
    Size origSize = new Size(currentTabContent.ActualWidth, currentTabContent.ActualHeight);
    Transform origTransform = currentTabContent.LayoutTransform;

    /// 3.  Transform currentTabContent (expose print panels, move stuff around etc) - 
        //do this inside TabItem class
    currentTabContent.SetupPrinting();

    /// 4.  Make changes outside TabItem (skin, page-scale)
        // skin
    resources.MergedDictionaries.Add(Application.LoadComponent(new Uri(@"Skin/PrintDictionary.xaml", UriKind.Relative)) as ResourceDictionary);
    Application.Current.Resources = resources;
        // page-scale
    double scale = Math.Min(pageWidth / currentTabContent.ActualWidth,
                            pageLength / currentTabContent.ActualHeight);

    // ****Uncomment next line - printing magic works.**** //
    // MessageBox.Show(string.Format("scaling by {0}", scale));
    System.Threading.Thread.Sleep(250);

    currentTabContent.LayoutTransform = new ScaleTransform(scale, scale);

    //Measure and Arrange
    currentTabContent.Measure(pageSize);
    ((UIElement)currentTabContent).Arrange(new Rect(
         new Point((capabilities.PageImageableArea.OriginWidth + pageMargin),
             (capabilities.PageImageableArea.OriginHeight + pageMargin)), pageSize));

    System.Threading.Thread.Sleep(250);

    /// 5. Print (Finally!)
    print.PrintVisual(currentTabContent, "Print Results");

    /// 6. Return everything to normal (undo 3, then 4)
        // undo 3.
    currentTabContent.TearDownPrinting();
        // undo 4.
    Application.Current.Resources = origSkin;
    scale = Math.Max(currentTabContent.ActualWidth / pageWidth,
                                    currentTabContent.ActualHeight / pageLength);
    currentTabContent.LayoutTransform = new ScaleTransform(1 / scale, 1 / scale);

    currentTabContent.Measure(origSize);
    ((UIElement)currentTabContent).Arrange(new Rect(0, 0, tabWidth, tabHeight));
  }
}

正如您所看到的,我尝试添加几个System.Threading.Thread.Sleep(250);,以防需要更多时间来识别更改,但这没有任何效果。 PrintDialog()电话的奇怪之处也是出于类似的原因。以通常的方式调用它没有任何区别。

任何人都可以告诉我为什么没有MessageBox调用我的打印功能不起作用,或者告诉我如何模拟MessageBox调用以使程序虚张声势地工作? 很多很多TIA

1 个答案:

答案 0 :(得分:0)

您可能遗漏的部分是MessageBox.Show();刷新了UIElement

所以如果你使用以下代码手动补充你的UIElement就足够了

  ui.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));// activates ui.InvalidateMeasure(); 
  ui.Arrange(new Rect(new Point(0, 0), ui.DesiredSize));                 // activates ui.InvalidateArrange();

  ui.UpdateLayout(); // <-- refreshed your UIElement

这至少在我的案例中起作用

旁注:
您不应该直接致电ui.Invalidate...,因为如果您没有更改措施或安排,因为UpdateLayout()不会刷新您的UIElement AFAIK