Wolfgang, thank you for the quick response. First, I would like to say that I prefer FlexGrid's own PrintGrid method, because, as you can see, the output is (apart from known errors) much better - more like the actual printscreen from the application.
I will try to explain what I do in my code. First, I have a member variable, which contains (calculated) data to tell GetMergedRange which cells should be merged.
In OwnerDrawCell, I first do:
CellRange range = grid.GetMergedRange(
e.Row,
e.Col);
int numOfCells = range.c2 - range.c1;
to acquire the number of cells. I then apply custom styles to cells (not just merged cells, but all other, too), via e.Style property. The main part of code is pasted below.
First I set what to draw (background and border).
I create rectangle the size of one cell. The reason I draw bitmaps in every merged cell is that I cannot have bitmaps for every possible merged length. Instead, I have (basically) 3 bitmaps. One for start, one for middle part (which repeats) and one for ending.
e.DrawCell(DrawCellFlags.Background | DrawCellFlags.Border);
Point cellPoint = e.Bounds.Location;
Rectangle rect = new Rectangle();
rect.Location = cellPoint;
rect.Width = CellWidth;
rect.Height = RowHeight;
// everything in the past has the same grey images
planStatusID = planDateTo >= DateTime.Today.Date
? (int)planRow.PlanStatusID
: Const.NullID;
if (planDateTo > m_StartDate.AddDays(GridLength - 1) ||
planDateTo > currentDate.AddDays(numOfCells))
{
numOfCells++;
}
if (planDateFrom == currentDate)
{
// here the starting bitmap is drawn at the beginning of merged cells:
e.Graphics.DrawImage(
m_PlanStatusStartBitmap[planStatusID],
rect);
// if previous dateTo matches current dateFrom and plan types also match,
// then draw ending image for previous plan
if (planDateFrom == previousPlanDateTo &&
m_PlanPlanTypeEnum == m_PreviousPlanPlanTypeEnum)
{
e.Graphics.DrawImage(
m_PlanStatusEndBitmap[previousPlanPlanStatusID],
rect);
}
numOfCells--;
rect.X += CellWidth;
}
for (int nMiddle = 0; nMiddle < numOfCells; nMiddle++)
{
if (nMiddle > 0)
{
rect.X += CellWidth;
}
// here the code iterates through merged length and draws "middle" bitmap
e.Graphics.DrawImage(
m_PlanStatusMiddleBitmap[planStatusID],
rect);
}
if (planDateTo <= m_StartDate.AddDays(GridLength - 1))
{
if (planDateTo > currentDate &&
numOfCells > 0)
{
rect.X += CellWidth;
}
// and at the end, "ending" bitmap is drawn
e.Graphics.DrawImage(
m_PlanStatusEndBitmap[planStatusID],
rect);
}
// then, caption is written in merged cells. I will supply this method below.
if (numOfCells > 0)
{
DrawBookingCaption(
e,
planRow,
planStatusID,
numOfCells);
}
// basically, what I do here is, I create rectangle the size of merged cells, and the caption is written (drawn) into that particular cell.
/// <summary>
/// Draws booking caption.
/// </summary>
/// <param name="p_EventArgs">Inherited event args</param>
/// <param name="p_PlanRow">Booking plan record</param>
/// <param name="p_CorrectedPlanStatusID">Corrected plan status ID</param>
/// <param name="p_NumOfCells">Number of cells</param>
private void DrawBookingCaption(
OwnerDrawCellEventArgs p_EventArgs,
BookingPlanDataSet.BookingPlanTRow p_PlanRow,
int p_CorrectedPlanStatusID,
int p_NumOfCells)
{
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
sf.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.NoClip;
sf.LineAlignment = StringAlignment.Near;
sf.Trimming = StringTrimming.EllipsisCharacter;
string caption;
if (p_PlanRow.PlanStatusID > 4)
{
caption = p_PlanRow.BookingCaption;
}
else
{
caption = string.Format(
"{0} ({1}€)",
p_PlanRow.BookingCaption,
string.Format(
"{0:N2}",
CalculatePrice(p_PlanRow)));
}
SizeF sz = p_EventArgs.Graphics.MeasureString(
caption,
grid.Font,
p_PlanRow.DateFrom < m_StartDate
? p_NumOfCells * CellWidth
: (p_NumOfCells + 1) * CellWidth - BookingCaptionOffset,
sf);
RectangleF rf = new RectangleF();
rf.X = p_PlanRow.DateFrom < m_StartDate
? p_EventArgs.Bounds.X
: p_EventArgs.Bounds.X + BookingCaptionOffset;
rf.Y = p_EventArgs.Bounds.Y + (p_EventArgs.Bounds.Height - sz.Height) / 2;
rf.Width = sz.Width;
rf.Height = sz.Height;
p_EventArgs.Graphics.DrawString(
caption,
grid.Font,
p_PlanRow.PlanStatusID == 6 && p_CorrectedPlanStatusID != Const.NullID
? Brushes.White
: Brushes.Black,
rf,
sf);
}
I hope you got better picture of the problem. I have to merge cells, because I don't know how to write captions across multiple cells, if they are not merged. Also, I don't know how to draw bitmaps (of variable cell lengths), other than combining them like I do. Do you have any other idea how to accomplish all that?
Thanks!