打印ListBox自定义项目

时间:2014-10-21 12:44:36

标签: c# wpf printing listbox

我是WPF新手,想要打印控件中显示的ListBox控件自定义项。 ListBox项结构如下:

<StackPanel Orientation="Vertical" HorizontalAlignment="Center" x:Name="PanelContainer">
    <Border CornerRadius="5" BorderThickness="2" BorderBrush="DarkBlue" x:Name="PanelMessage">
        <StackPanel Orientation="Horizontal" Background="{Binding Color}">
            <StackPanel Orientation="Vertical">
                <Image Source="{Binding SenderImage}" Width="50" Height="50" Stretch="Uniform" />
                <TextBlock Text="{Binding Sender}" TextAlignment="Center" Width="50" TextWrapping="Wrap" />
            </StackPanel>
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                <Image Source="{Binding IsRead}" Width="15" Height="15" Stretch="Uniform" 
                       VerticalAlignment="Top" />
                <StackPanel Orientation="Vertical" Margin="5">
                    <TextBlock x:Name="txtbTime" Text="{Binding TimeCreated}" />
                    <TextBlock x:Name="txtbMessage" Text="{Binding MessageBody}" 
                               TextWrapping="WrapWithOverflow" HorizontalAlignment="Stretch" />
                </StackPanel>
            </StackPanel>
        </StackPanel>
    </Border>
</StackPanel>

我的打印代码如下:

UIElement myListBoxItem =
   (UIElement) (lbMessages.ItemContainerGenerator.ContainerFromItem((Message) lbMessages.Items[i]));
if (myListBoxItem != null)
{
   string element = XamlWriter.Save(myListBoxItem);
   MemoryStream ms = new MemoryStream();
   XamlWriter.Save(element, ms);
   ms.Seek(0, SeekOrigin.Begin);
   object obj1 = XamlReader.Load(ms);
   BlockUIContainer bc = new BlockUIContainer();
   bc.Child = obj1 as UIElement;
   fd.Blocks.Add(bc);
   ms.Close();
}
PrintDialog dialog = new PrintDialog();
if (dialog.ShowDialog() == true)
   dialog.PrintDocument(idpSource.DocumentPaginator, "Hello WPF Printing."); 

我的结果是一个清晰的页面。

我希望有些人可以帮助我,谢谢。

2 个答案:

答案 0 :(得分:0)

我对DataGrid和ListView有同样的问题,我用这个扩展解决了它。 我认为您可以为ListBox调整此代码,我希望这可以帮助您。

问候。

using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.IO.Packaging;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Xps;
using System.Windows.Xps.Packaging;

var view = objToPrint as ListView;
if (view != null)
  PrintExtensions.PrintPreview(view);
else
{
  var grid = objToPrint as DataGrid;
  if (grid != null)
    PrintExtensions.PrintPreview(grid);                                            
} 

public static class PrintExtensions
{
  private static FixedDocument ToFixedDocument(UIElement element, PrintDialog dialog)
  {
        var capabilities = dialog.PrintQueue.GetPrintCapabilities(dialog.PrintTicket);
        var pageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight);
        var extentSize = new Size(capabilities.PageImageableArea.ExtentWidth,capabilities.PageImageableArea.ExtentHeight);

        var fixedDocument = new FixedDocument();

        element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        element.Arrange(new Rect(new Point(0, 0), element.DesiredSize));

        double totalHeight = element.DesiredSize.Height;

        double yOffset = 0d;
        while (yOffset < totalHeight)
        {
            var brush = new VisualBrush(element)
                                    {
                                        Stretch = Stretch.None,
                                        AlignmentX = AlignmentX.Left,
                                        AlignmentY = AlignmentY.Top,
                                        ViewboxUnits = BrushMappingMode.Absolute,
                                        TileMode = TileMode.None,
                                        Viewbox = new Rect(0, yOffset, extentSize.Width, extentSize.Height)
                                    };

            var pageContent = new PageContent();
            var page = new FixedPage();
            ((IAddChild)pageContent).AddChild(page);

            fixedDocument.Pages.Add(pageContent);
            page.Width = pageSize.Width;
            page.Height = pageSize.Height;

            var canvas = new Canvas();
            FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
            FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
            canvas.Width = extentSize.Width;
            canvas.Height = extentSize.Height;
            canvas.Background = brush;

            page.Children.Add(canvas);

            yOffset += extentSize.Height;
        }
        return fixedDocument;
    }

    private static ListView ToPrintFriendlyGrid(ListView source)
    {
        var listView = new ListView {ItemsSource = source.ItemsSource};

        listView.SetValue(ListViewPagingBehavior.EnablePagingProperty, false);
        listView.Items.Filter = null;

        ScrollViewer.SetVerticalScrollBarVisibility(listView, ScrollBarVisibility.Hidden);
        ScrollViewer.SetHorizontalScrollBarVisibility(listView, ScrollBarVisibility.Hidden);

        var gridView = (GridView)source.View;
        var newGridView = new GridView();

        double width = 0;
        foreach (var viewColumn in gridView.Columns)
        {
            var column = viewColumn;
            if (column != null)
            {
                var columnType = column.GetType();
                var newColumn = (GridViewColumn) Activator.CreateInstance(columnType);

                var objPropertiesArray = columnType.GetProperties();
                foreach (PropertyInfo info in objPropertiesArray)
                {
                    var pin = columnType.GetProperty(info.Name);
                    if (pin != null)
                    {
                        if (pin.CanWrite)
                        {
                            object obj = info.GetValue(column, null);
                            pin.SetValue(newColumn, obj, null);
                        }
                    }
                }
                width += column.Width;

                newGridView.Columns.Add(newColumn);
            }
        }

        listView.Width = width;

        var dialog = new PrintDialog();

        double d = Math.Round(dialog.PrintableAreaHeight / 21, 2); // elementi contenuti in una pagina
        double e = Math.Round(listView.Items.Count / d, 2); // numero di pagine ... anche se attualmente c'è qualche problema di impaginazione

        if (Math.Truncate(e) == 0)
            e = .95;

        listView.Height = dialog.PrintableAreaHeight * e;

        listView.View = newGridView;

        return listView;
    }

    private static DataGrid ToPrintFriendlyGrid(DataGrid source)
    {
        var newGridView = new DataGrid {ItemsSource = source.ItemsSource};

        ScrollViewer.SetVerticalScrollBarVisibility(newGridView, ScrollBarVisibility.Hidden);
        ScrollViewer.SetHorizontalScrollBarVisibility(newGridView, ScrollBarVisibility.Hidden);

        double width = 0;
        foreach (DataGridColumn gridColumn in source.Columns)
        {
            var column = gridColumn;
            if (column != null)
            {
                Type columnType = column.GetType();
                var newColumn = (DataGridColumn) Activator.CreateInstance(columnType);

                PropertyInfo[] objPropertiesArray = columnType.GetProperties();
                foreach (PropertyInfo info in objPropertiesArray)
                {
                    PropertyInfo pin = columnType.GetProperty(info.Name);
                    if (pin != null)
                    {
                        if (pin.CanWrite)
                        {
                            object obj = info.GetValue(column, null);
                            pin.SetValue(newColumn, obj, null);
                        }
                    }
                }
                width += column.ActualWidth;

                newGridView.Columns.Add(newColumn);
            }
        }

        newGridView.Width = width;

        var dialog = new PrintDialog();

        double d = Math.Round(dialog.PrintableAreaHeight / 21, 2); // elementi contenuti in una pagina
        double e = Math.Round(newGridView.Items.Count / d, 2); // numero di pagine ... anche se attualmente c'è qualche problema di impaginazione

        if (Math.Truncate(e) == 0)
            e = .95;

        newGridView.Height = dialog.PrintableAreaHeight * e;           

        return newGridView;
    }

    public static void PrintPreview(ListView source)
    {
        var window = new Window {Title = "Print Preview"};

        var documentViewer = new DocumentViewer
                                            {
                                                Document =
                                                    ToFixedDocument(ToPrintFriendlyGrid(source), new PrintDialog())
                                            };
        window.Content = documentViewer;

        window.ShowDialog();
    }

    public static void Print(ListView source, bool showDialog)
    {
        var dialog = new PrintDialog();
        bool? dialogResult = showDialog ? dialog.ShowDialog() : true;

        if (dialogResult == true)
        {
            var viewer = new DocumentViewer
                                        {
                                            Document = ToFixedDocument(ToPrintFriendlyGrid(source), dialog)
                                        };
            dialog.PrintDocument(viewer.Document.DocumentPaginator, null);
        }
    }

    public static void PrintPreview(DataGrid source)
    {
        var window = new Window { Title = "Print Preview" };

        var documentViewer = new DocumentViewer
        {
            Document =
                ToFixedDocument(ToPrintFriendlyGrid(source), new PrintDialog())
        };
        window.Content = documentViewer;

        window.ShowDialog();
    }

    public static void Print(DataGrid source, bool showDialog)
    {
        var dialog = new PrintDialog();
        bool? dialogResult = showDialog ? dialog.ShowDialog() : true;

        if (dialogResult == true)
        {
            var viewer = new DocumentViewer
            {
                Document = ToFixedDocument(ToPrintFriendlyGrid(source), dialog)
            };
            dialog.PrintDocument(viewer.Document.DocumentPaginator, null);
        }
    }        
}

答案 1 :(得分:0)

经过一些搜索,我发现了一个解决方案,如下所示: 1.迭代我的ListBox项目。 2.使用值生成表。 3.打印保存值的表格。

代码:

    foreach (Message message in lbMessages.Items)
            {

                TableRowGroup _MessageContainer = new TableRowGroup();

                // Rows
                TableRow _TimeCreated = new TableRow();
                TableRow _imageRow = new TableRow();
                TableRow _TimeRow = new TableRow();

                // first row
                TableCell xcell = new TableCell(new Paragraph(new Run("Image is here")));
                xcell.RowSpan = 2;
                TableCell _TimeCell = new TableCell(new Paragraph(new Run(message.TimeCreated.ToString())));
                _TimeCreated.Cells.Add(xcell);
                _TimeCreated.Cells.Add(_TimeCell);

                // Second Row.
                xcell = new TableCell(new Paragraph(new Run(message.MessageBody)));
                _imageRow.Cells.Add(xcell);

                // Third Row
                xcell = new TableCell(new Paragraph(new Run(message.Sender)));
                xcell.ColumnSpan = 2;

                _MessageContainer.Rows.Add(_TimeCreated);
                _MessageContainer.Rows.Add(_imageRow);
                _MessageContainer.Rows.Add(_TimeRow);

                Table xtable = new Table();
                xtable.RowGroups.Add(_MessageContainer);
                xtable.CellSpacing = 3;
                xtable.Background = Brushes.White;

                document.Blocks.Add(xtable);
}

打印代码:

PrintDialog dialog = new PrintDialog();
            if (dialog.ShowDialog() == true)
            {
                IDocumentPaginatorSource idpSource = document;
                dialog.PrintDocument(idpSource.DocumentPaginator, "All Messages");
            }