mjaniaut Ответов: 1

Как напечатать один и тот же элемент управления на нескольких страницах


Всем привет,

У меня есть сетка с некоторым элементом управления (Textblock), у меня также есть две кнопки для навигации по странице.

Когда я меняю страницу, содержимое текстового блока меняется.

Я хотел бы распечатать всю страницу в формате pdf или на принтере. Но я не приезжаю. страница, кажется, не обновляется правильно.

Содержание всех страниц всегда одно и то же.

При необходимости я могу сделать тестовый проект.

Спасибо за вашу помощь.

Что я уже пробовал:

/// <summary>
/// Print the current view to PDF or printer
/// </summary>
/// <param name="sender"></param>
/// <param name="re"></param>
private void Print_Click(object sender, RoutedEventArgs re)
{

    const double CMTOPIXEL = 37.79527559055;
    // size expected = 18 cm * 10.3 cm
    Size ExpectedSize = new Size(18 * CMTOPIXEL, 10.3 * CMTOPIXEL);

    System.Windows.FrameworkElement e = printPanel as System.Windows.FrameworkElement;
    if (e == null)
        return;
    // if all ECU doesn't contains something => not print
    if (affectedPinByECU.Count == 0)
        return;

    // select printer and get printer settings
    PrintDialog pd = new PrintDialog();
    pd.SelectedPagesEnabled = true;
    pd.PageRangeSelection = PageRangeSelection.SelectedPages;

    // if windows is close without print
    if (pd.ShowDialog() != true) return;

    List<int> toPrint = new List<int>();
    if (pd.PageRangeSelection == PageRangeSelection.AllPages)
    {
        for (int i = 0; i < MaxNumberOfECU; i++)
            toPrint.Add(i);
    }
    else
    {
        foreach (var usedpage in affectedPinByECU)
        {
            toPrint.Add(usedpage.Key);
        }
    }
    // create a document
    FixedDocument document = new FixedDocument();
    document.DocumentPaginator.PageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
    PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);
    Thickness margin = new Thickness(10);

    double scalex = ExpectedSize.Width / e.ActualWidth;
    double scaley = ExpectedSize.Height / e.ActualHeight;

    e.RenderTransform = new ScaleTransform(scalex, scaley);

    Size visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth - margin.Left - margin.Right, capabilities.PageImageableArea.ExtentHeight - margin.Top - margin.Bottom);

    //update the layout of the visual to the printer page size.
    e.Measure(visibleSize);
    e.Arrange(new Rect(visibleSize));
                   e.UpdateLayout();

    // for each page to pring
    foreach (var usedpage in toPrint)
    {
        FixedPage page1 = new FixedPage();
        page1.Width = document.DocumentPaginator.PageSize.Width;
        page1.Height = document.DocumentPaginator.PageSize.Height;

        Canvas canvas = UpdateECUpages(e, usedpage, visibleSize, capabilities.PageImageableArea, margin);

        page1.Children.Add(canvas);

        PageContent page1Content = new PageContent();
        ((IAddChild)page1Content).AddChild(page1);

        document.Pages.Add(page1Content);
    }

    // go back to the current ecu;

    vUpdateECU(indexECU);
    // and print
    pd.PrintDocument(document.DocumentPaginator, "My first document");

    e.RenderTransform = new ScaleTransform(1, 1);
}

private Canvas UpdateECUpages(FrameworkElement e, int i, Size visibleSize, PageImageableArea PageImageableArea, Thickness margin)
{

    vUpdateECU(i);

    // clone the element
    Canvas newCanvas = new Canvas();
    DockPanel dk = new DockPanel();

    // Add text at the begin
    TextBlock page1Text = new TextBlock();
    if (i == 0)
        page1Text.Text = "Master";
    else
        page1Text.Text = "Slave " + i;
    page1Text.FontSize = 40;
    page1Text.Margin = new Thickness(10);
    page1Text.HorizontalAlignment = HorizontalAlignment.Center;
    DockPanel.SetDock(page1Text, Dock.Top);
    dk.Children.Add(page1Text);

    newCanvas.Children.Add(dk);

    e.UpdateLayout();
    VisualBrush vb = new VisualBrush(e);


    vb.Stretch = Stretch.None;
    vb.AlignmentX = AlignmentX.Center;
    vb.AlignmentY = AlignmentY.Top;
    vb.ViewboxUnits = BrushMappingMode.Absolute;
    vb.TileMode = TileMode.None;
    vb.Viewbox = new Rect(0, 0, visibleSize.Width, visibleSize.Height);

    FixedPage.SetLeft(newCanvas, PageImageableArea.OriginWidth);
    FixedPage.SetTop(newCanvas, PageImageableArea.OriginHeight);

    newCanvas.Width = visibleSize.Width;
    newCanvas.Height = visibleSize.Height;
    newCanvas.Background = vb;
    newCanvas.Margin = margin;
    return newCanvas;
}

1 Ответов

Рейтинг:
5

Roman Lerman

Привет,ваш подход мне не знаком, но я вижу по крайней мере одну проблему в вашем примере. Метод

private Canvas UpdateECUpages(FrameworkElement e, int i, Size visibleSize, PageImageableArea PageImageableArea, Thickness margin)
получение FrameworElement e, но возвращает новый объект Canvas. Вы можете назначить новое содержимое (сохраняя ссылку) элементу e как newCanvas и вернуть e, или вы можете изменить сигнатуру метода на
private void UpdateECUpages(ref FrameworkElement e, int i, Size visibleSize, PageImageableArea PageImageableArea, Thickness margin)
а в методе присвоите новое значение e. e = newCanvas; а затем используйте объект e в следующем коде. Другой вариант-использовать другой подход, см. принятое решение здесь [^]
Извините за мой английский и не полный ansver.

Наилучшие пожелания,
Римский