C # PrintDocument - проблема макета таблицы / сетки - PullRequest
1 голос
/ 22 декабря 2011

Я пытаюсь распечатать некоторые данные на странице в формате таблицы / сетки. На данный момент у меня это работает, но все вытягивается вручную. Довольно жестко запрограммированные значения ширины и высоты каждой ячейки.

То, что я пытаюсь сделать, это превратить его в более общее решение. Создайте какой-нибудь объект, содержащий все данные, и сделайте так, чтобы он сам отображался.

Проблема, с которой я сталкиваюсь, заключается в том, чтобы найти способ определить высоту каждой ячейки, убедившись, что она достаточно велика для данных, содержащихся в ней.

То, что у меня сейчас есть, примерно так:

protected override void OnPrintPage(PrintPageEventArgs e)
{
    DrawPageHeader();

    List<ItemDTO> ItemsForPage = GetItemsToRenderOnThisPage();

    for (int i = 1; i < ItemsForPage.Count; i ++)
    {
        //Each column is rendered in this method. The X and Y start positions are passed, plus the width of the column.
        DrawColumn(g, ItemsForPage[0], column1X, totalWidth / ItemsForPage.Count, itemStartY);
    }
}

private int DrawColumnForItem(Graphics g, ItemDTO item, int startPoint, int columnWidth, int rowPosition)
{
    //Draw the vertical Lines
    g.DrawLine(linePen, lineLeft, rowPosition, lineLeft, lineHeight);
    g.DrawLine(linePen, lineRight, rowPosition, lineRight, lineHeight);
    g.DrawLine(linePen, startPoint - 2, rowPosition, startPoint - 2, lineHeight);

    // (85 characters max field) 
    g.DrawLine(linePen, lineLeft, rowPosition, lineRight, rowPosition);
    g.DrawString("Description", smallBoldFont, Brushes.Black, 3, ++rowPosition);
    g.DrawString(item.Desc, smallFont, Brushes.Black, new Rectangle(startPoint, rowPosition, columnWidth, rowIncrement * 2));
    rowPosition += rowIncrement;
    rowPosition += rowIncrement;

    //Details (250 characters max)
    g.DrawLine(linePen, lineLeft, rowPosition, lineRight, rowPosition);
    g.DrawString("Detailed Desc", smallBoldFont, Brushes.Black, 3, ++rowPosition);
    g.DrawString(item.DetailedDescription, smallFont, Brushes.Black, new Rectangle(startPoint, rowPosition, columnWidth, rowIncrement * 2));
    rowPosition += rowIncrement;
    rowPosition += rowIncrement;
    rowPosition += rowIncrement;

    //Gender (M or F)
    g.DrawLine(linePen, lineLeft, rowPosition, lineRight, rowPosition);
    g.DrawString("Gender", smallBoldFont, Brushes.Black, 3, ++rowPosition);
    g.DrawString(item.Gender.ToString(), smallFont, Brushes.Black, startPoint, rowPosition);
    rowPosition += rowIncrement;
}

Вы видите идею. Я рисую каждую линию. Затем текст, затем увеличивая положение строки, чтобы перейти на следующую строку.

Итак, есть 3 поля выше. Каждый из них имеет различный максимальный размер, и, следовательно, каждый из них может нуждаться в большей или меньшей «ячейке».

Так что я догадываюсь, что мне действительно нужен метод определения того, сколько места займет данный фрагмент текста. g.MeasureString даст мне ширину, но не высоту (если она переносится на несколько строк). Поэтому я не знаю, сколько строк дать.

Кроме того, проблема, связанная с тем, что он измеряется вручную, заключается в том, что каждый раз, когда я делаю изменение, мне нужно пройти и снова начать настройку, чтобы убедиться, что все выровнено.

Я собираюсь делать подобные документы, так что было бы здорово, если бы в основном это можно было автоматизировать.

Надеюсь, это имеет смысл.

1 Ответ

1 голос
/ 20 сентября 2017

Да, я знаю, что это старо, но это не повод, чтобы оно болталось без ответа.

Вам необходимо использовать метод GetHeight или MeasureString . Любой из них требует шрифта, который вы хотите измерить, поэтому используйте ваш smallFont там, где его можно определить (например, для целей)

smallFont = New Font("Arial", 8, FontStyle.Regular)

Вы можете получить высоту по:

smallFont.GetHeight(g)

попеременно

g.MeasureString("TestString", smallFont)
...