주 콘텐츠로 건너뛰기

 none
C# - Result from e.Graphics.DrawString does not output what I expect RRS feed

  • 질문

  •         private void pd_PrintPage(object sender, PrintPageEventArgs e)
            {
                float linesPerPage = 0;
                float yPos = 0;
                float count = 0;
                float leftMargin = e.MarginBounds.Left;
                float topMargin = e.MarginBounds.Top;
                string line = null;
                // Calculate the number of lines per page.
                linesPerPage = e.MarginBounds.Height / _font.GetHeight(e.Graphics);
               
                while (count < linesPerPage && ((line = _reader.ReadLine()) != null))
                {
                    if (line.Contains("[page_break]"))
                        break;

                     yPos = topMargin + (count * _font.GetHeight(e.Graphics));
                    e.Graphics.DrawString(line, _font, Brushes.Black, leftMargin, yPos, new StringFormat());
                   
                    count++;
                }
                // Set page count
                PageCount += 1;

                // If more lines exist, print another page.
                if (line != null)
                    e.HasMorePages = true;
                else
                    e.HasMorePages = false;
            }

    The coding above works fine except with some lines longer than the margin (i.e. the length too long but it didn't go to next line or wordwrap), so it got cropped.  I believe there is some problem for these lines

                     yPos = topMargin + (count * _font.GetHeight(e.Graphics));
                    e.Graphics.DrawString(line, _font, Brushes.Black, leftMargin, yPos, new StringFormat());

    Can somebody help how to correct this problem?

    thank you



    • 이동됨 CoolDadTx 2020년 1월 14일 화요일 오후 2:46 Winforms related
    2020년 1월 14일 화요일 오전 10:36

답변

  • You can use a call to e.Graphics.MeasureString to determine how many pixels of space will be needed for the string. If the resulting value is larger than the width that you have available for writing the string, then you split it at a suitable location, for example, at the blank space between two words. You then use DrawString to write the first fragment of the string, increment yPos, and write the rest of the string in the second line. If your strings can be long enough to require more than two lines, then you have to repeat the process, splitting the string again until all the portions can fit in the allocated space. Of course, this will complicate the logic in your loop, because you may be at the end of the page and the split fragments may overflow to the next page. To avoid creating an excessive complexity, I suggest first using ReadLine to load all the lines into a structure in memory, such as a List<string>, then measure all the strings in the list and split those that require it, insert the pieces back into the list, and finally do the printing from the list instead of printing directly from the _reader.
    2020년 1월 14일 화요일 오후 1:07

모든 응답

  • You can use a call to e.Graphics.MeasureString to determine how many pixels of space will be needed for the string. If the resulting value is larger than the width that you have available for writing the string, then you split it at a suitable location, for example, at the blank space between two words. You then use DrawString to write the first fragment of the string, increment yPos, and write the rest of the string in the second line. If your strings can be long enough to require more than two lines, then you have to repeat the process, splitting the string again until all the portions can fit in the allocated space. Of course, this will complicate the logic in your loop, because you may be at the end of the page and the split fragments may overflow to the next page. To avoid creating an excessive complexity, I suggest first using ReadLine to load all the lines into a structure in memory, such as a List<string>, then measure all the strings in the list and split those that require it, insert the pieces back into the list, and finally do the printing from the list instead of printing directly from the _reader.
    2020년 1월 14일 화요일 오후 1:07
  • brilliant, you pointed out several good points, very impressed :-)

    I dipped deeper on e.Graphics.DrawString to see if it's possible to first draw a Rectangle and fill the text inside so every "line" is being wrapped up.

    Do you guys have similar coding for reference?  thanks

    2020년 1월 15일 수요일 오전 1:50
  • Hi iHandler,

    Thank you for posting here.

    You can refer to this link to draw Wrapped Text in a Rectangle.

    How to: Draw Wrapped Text in a Rectangle

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2020년 1월 15일 수요일 오전 9:18