C # WinForm PrintPreviewDialog: предварительный просмотр печати для отображения нескольких меток на странице

#c# #winforms #print-preview

#c# #winforms #предварительный просмотр печати

Вопрос:

У меня есть WinForm для создания меток.

Он вызывает a PrintPreviewDialog и отображает информацию, используя PrintPageEventArgs в PrintDocument ‘s PrintPageEventHandler .

 void Document_Printed(object sender, PrintPageEventArgs e) {
  // Code goes here
}
  

Если метка представляет собой небольшую адресную метку размером 8,5×11 букв, вместо того, чтобы видеть одну метку в PrintPreviewDialog , я хочу видеть количество меток, которые помещаются на нее PageSettings.PaperSize .

Пример: Скажем, четыре (4) элемента помещаются на выбранный носитель (этикетка для обычного принтера или что-либо еще).

  • Если мой конечный пользователь указывает от 1 до 4 копий для печати, я хочу, чтобы в моем диалоговом окне предварительного просмотра отображались все копии.

  • Если мой конечный пользователь указывает более четырех (4) элементов, в диалоговом окне предварительного просмотра печати должно отображаться несколько страниц (я никогда раньше не просматривал несколько страниц).).

Я могу изменить размер своих данных в соответствии с размером моей метки, но я не знаю, как заставить мои PrintPageEventHandler отображать более 1 метки на PrintPreviewDialog .

Может кто-нибудь показать мне, как это делается? Как мне отобразить и распечатать несколько меток (документов?) на листе?

РЕДАКТИРОВАТЬ: Вот мой код, основанный на двух объектах RectangleF: pageRect и LabelRect:

 void Document_Printed(object sender, PrintPageEventArgs e) {
  if (printPreview == null) return;
  int labelSupport = 1;
  RectangleF pageRect = new RectangleF(0, 0, printPreview.Document.DefaultPageSettings.PaperSize.Width, printPreview.Document.DefaultPageSettings.PaperSize.Height);
  float fW = (pageRect.Width < LabelRect.Width) ? (pageRect.Width / LabelRect.Width) : (LabelRect.Width / pageRect.Width);
  float fH = (pageRect.Height < LabelRect.Height) ? (pageRect.Height / LabelRect.Height) : (LabelRect.Height / pageRect.Height);
  // START Portion I need HELP with!
  if (1 < LabelsPerPage) {
    if (Landscape) {
    } else {
    }
  } else {
    if (Landscape) {
    } else {
    }
  }
  // END (I think) Portion I need HELP with!
  SizeF ratio = new SizeF(fW, fH);
  Graphics G = e.Graphics;
  foreach (Label item in labelList) {
    Console.WriteLine(item.Name);
    using (SolidBrush b = new SolidBrush(Color.Black)) {
      using (Pen p = new Pen(b)) {
        float x = ratio.Width * (float)item.Location.X;
        float y = ratio.Height * (float)item.Location.Y;
        float w = ratio.Width * (float)item.Size.Width;
        float h = ratio.Height * (float)item.Size.Height;
        RectangleF r = new RectangleF(x, y, w, h);
        G.DrawString(item.Text, item.Font, b, r);
      }
    }
  }
}
  

ПРАВКА 2: мне нужен способ распечатать 2 или более документов на 1 странице. Пока этот ключевой момент не рассмотрен. Это ответ, который мне нужен.

Комментарии:

1. Возможно, было бы полезно просмотреть часть вашего кода рендеринга PrintPageEventHandler

2. Понятно. Добавлен пример кода, начинающийся с раздела РЕДАКТИРОВАТЬ: .

3. Это выглядит нормально. Я бы поставил точку останова в верхней части метода и прошелся по нему построчно, чтобы убедиться, что то, что вы ожидаете, происходит на самом деле. Например, меняются ли значения размера и местоположения для каждого элемента в цикле рисования? Похоже, что так и должно быть, но если вы неправильно присвоили эти значения в другом месте, то, возможно, вы рисуете одно и то же снова или каждую новую метку поверх предыдущих.

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

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

Ответ №1:

Печатать страницы после первой на самом деле очень просто: просто установите для свойства PrintPageEventArgs HasMorePages значение true.

Самое сложное — знать, когда это нужно остановить, установив HasMorePages значение false . Я сделал это, сохранив данные для каждого задания печати в списке и используя значение индекса, чтобы отслеживать, где я нахожусь в этом списке.

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

 void Document_Printed(object sender, PrintPageEventArgs e) { 
   // Get data for this page.
   //xxx =  pageDataList[indexValue];

   // Code to print stuff.

   indexValue  ;
   e.HasMorePages = (pageDataList.Length == indexValue);
}
  

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

Комментарии:

1. Вы знаете, я видел HasMorePages свойство, но я просто просматривал его, а не устанавливал его.

2. Крысы. Нажатие [CR] зафиксировало комментарий вместо перехода к следующей строке. {вздох!} В любом случае, я попробую это, чтобы посмотреть, смогу ли я распечатать / отобразить несколько маленьких меток на листе бумаги размером 8,5×11.

3. Мне пришлось уменьшить мою виртуальную страницу на количество страниц, которые я хотел отобразить на экране, но в остальном это сработало!