Custom RowPaint does not work in Print event

8 posts, 1 answers
  1. Rodrigo Cesar
    Rodrigo Cesar avatar
    13 posts
    Member since:
    Oct 2014

    Posted 20 Jul 2018 Link to this post

    I'm using RowPaint event to "merge" cells. But when Printing it is not using the RowPaint event.

    I tried to use PrintCellPaint event. But Row of event args are different. One is GridDataRowElement and other is GridViewDataRowInfo.

    How can I use the same code to both events?

    private void radGridView2_RowPaint(object sender, GridViewRowPaintEventArgs e)
    {
        var dataRow = e.Row as GridDataRowElement;
        if (dataRow == null)
            return;
     
        var value = Convert.ToInt32(dataRow.RowInfo.Cells["Group"].Value);
        if (value == -1)
            return;
     
        var startCell = e.Row.VisualCells[2];
     
        var leftPos = startCell.PointToControl(startCell.Bounds.Location).X + (startCell.TableElement.CellSpacing * startCell.ColumnIndex);
     
        var msgLocation = new Rectangle(leftPos + 1, 1, e.Row.Bounds.Width - leftPos - 2, e.Row.Bounds.Height - 2);
     
        e.Graphics.FillRectangle(new SolidBrush(Color.White), msgLocation);
        e.Graphics.DrawString(EventLogs[value], e.Row.Font, new SolidBrush(Color.Black), msgLocation);
     
        var textSize = e.Graphics.MeasureString(EventLogs[value], e.Row.Font, msgLocation.Width);
        //if (textSize.Height > dataRow.Size.Height)
            startCell.RowInfo.Height = (int)textSize.Height;
    }
  2. Hristo
    Admin
    Hristo avatar
    1512 posts

    Posted 23 Jul 2018 Link to this post

    Hello Rodrigo,

    The RowPaint event allows modifications of how the elements are painted in the grid and it will not fire while printing the control. PrintCellPaintEventArgs do not expose the row element object as it is part of the virtualized visual tree building the control. The actual data row object is exposed and you perform customizations on how the cells will be painted, however, running the same code in both events would not be possible. Additional information is available here: https://docs.telerik.com/devtools/winforms/gridview/printing-support/events-and-customization.

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Rodrigo Cesar
    Rodrigo Cesar avatar
    13 posts
    Member since:
    Oct 2014

    Posted 23 Jul 2018 in reply to Hristo Link to this post

    Ok. But how can I do this "merge" cell in print? Is it possible in PrintCellPaint? (I don't understand why there isn't a PrintRowPaint event!)
  4. Answer
    Hristo
    Admin
    Hristo avatar
    1512 posts

    Posted 24 Jul 2018 Link to this post

    Hi Rodrigo,

    The merged cells you have achieved are a result of special painting and such customizations are not supported by the printing engine. While printing, entire rows are not painted rather only the cells and this is done one cell at a time, hence there is no row paint nor row formatting event. Yet, you can create a custom print renderer and implement the PrintRow method according to your local setup: 
    public class CustomTableViewDefinitionPrintRenderer : TableViewDefinitionPrintRenderer
    {
        public CustomTableViewDefinitionPrintRenderer(RadGridView grid)
            : base(grid)
        {
        }
     
        protected override void PrintRow(GridViewRowInfo row, TableViewRowLayout rowLayout, GridPrintSettings settings, int currentX, int currentY, Graphics graphics, Rectangle drawArea)
        {
            base.PrintRow(row, rowLayout, settings, currentX, currentY, graphics, drawArea);
             
            //...
        }
    }

    Then you can use the rendered like this: 
    this.radGridView1.PrintStyle.PrintRenderer = new CustomTableViewDefinitionPrintRenderer(this.radGridView1);

    I hope this information is useful.

    Regards,
    Hristo
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Rodrigo Cesar
    Rodrigo Cesar avatar
    13 posts
    Member since:
    Oct 2014

    Posted 24 Jul 2018 in reply to Hristo Link to this post

    Ok. That worked to me.

    Follow my render code if anyone has interest in it.

    public class CustomTableViewDefinitionPrintRenderer : TableViewDefinitionPrintRenderer
    {
        private RadGridView _grid;
        public EventHandler<RowPrintArgs> RowPrint;
     
        public CustomTableViewDefinitionPrintRenderer(RadGridView grid)
            : base(grid)
        {
            _grid = grid;
        }
     
        protected override void PrintRow(GridViewRowInfo row, TableViewRowLayout rowLayout, GridPrintSettings settings, int currentX, int currentY, Graphics graphics, Rectangle drawArea)
        {
            base.PrintRow(row, rowLayout, settings, currentX, currentY, graphics, drawArea);
     
            if (RowPrint != null)
            {
                var args = new RowPrintArgs()
                {
                    Row = row,
                    RowLayout = rowLayout,
                    PrintSettings = settings,
                    CurrentPos = new Point(currentX, currentY),
                    Graphics = graphics,
                    DrawArea = drawArea
                };
     
                RowPrint(_grid, args);
            }
        }
    }
     
    public class RowPrintArgs : EventArgs
    {
        public GridViewRowInfo Row { get; set; }
        public TableViewRowLayout RowLayout { get; set; }
        public GridPrintSettings PrintSettings { get; set; }
        public Point CurrentPos { get; set; }
        public Graphics Graphics { get; set; }
        public Rectangle DrawArea { get; set; }
    }

     

    And the use:

    private void RowPrintEvent(object sender, RowPrintArgs e)
    {
        if (!(e.Row.Cells["Group"].Value is int))
            return;
     
        var value = Convert.ToInt32(e.Row.Cells["Group"].Value);
        if (value == -1)
            return;
     
        var startCell = e.RowLayout.LayoutImpl.ArrangeInfos.First(x => x.Value.Column.FieldName.Equals("Id")).Value;
     
        var leftPos = startCell.OffsetX;
                 
        var msgLocation = new RectangleF(e.CurrentPos.X + leftPos + 1, e.CurrentPos.Y, e.RowLayout.DesiredSize.Width - leftPos - 2, e.Row.Height);
        msgLocation.Offset(1, 1);
        msgLocation.Width--;
        msgLocation.Height--;
     
        e.Graphics.FillRectangle(new SolidBrush(Color.White), msgLocation);
        e.Graphics.DrawString(EventLogs[value], e.PrintSettings.CellFont, new SolidBrush(Color.Black), msgLocation);
    }

     

    But I have other question. There is a way to adjust row height in print view?

  6. Hristo
    Admin
    Hristo avatar
    1512 posts

    Posted 25 Jul 2018 Link to this post

    Hi Rodrigo,

    Thank you for sharing your final solution with the community. I am also glad that I managed to help and the custom print renderer is working well in your project.

    Regards,
    Hristo
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  7. Rodrigo Cesar
    Rodrigo Cesar avatar
    13 posts
    Member since:
    Oct 2014

    Posted 25 Jul 2018 in reply to Hristo Link to this post

    Other question: There is a way to adjust row height in PrintRow function?
  8. Hristo
    Admin
    Hristo avatar
    1512 posts

    Posted 26 Jul 2018 Link to this post

    Hi Rodrigo,

    The row`s height is generated according to the applied height of the actual row in the grid. It is extracted in the virtual GetDataRowHeight  method in the print renderer class. As you are already using a custom TableViewDefinitionPrintRenderer you can also override the GetDataRowHeight method and change it according to your actual scenario.

    Regards,
    Hristo
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top