empira / PDFsharp

PDFsharp and MigraDoc Foundation for .NET 6 and .NET Framework
https://docs.pdfsharp.net/
Other
527 stars 130 forks source link

Cloned table does not set Parent property of Cell child objects - Exception at rendering #68

Closed AntonVonDelta closed 7 months ago

AntonVonDelta commented 10 months ago

Cloning a table doesn't properly set the parent of Cell objects. This leads to an NullReferenceException after calling pdfRenderer.RenderDocument();.

My solution was to change the getters Row, Table for Cell.cs and Table for Row.cs e.g:

        public Row Row {
            get {
                // Set in ResetCachedValues.
                if (_row != null)
                    return _row!;

                var castedParent = Parent as Cells;
                if (castedParent != null) {
                    _row = castedParent.Row;
                }

                return _row!;
            }
        }

Expected Behavior

No exception thrown.

Actual Behavior

Exception thrown "System.NullReferenceException: 'Object reference not set to an instance of an object.'" at MigraDoc.DocumentObjectModel.Visitors.CellComparer.Compare(Cell cellLhs, Cell cellRhs) on the line int rowCmpr = cellLhs.Row.Index - cellRhs.Row.Index; because cellRhs.Row is null.

Steps to Reproduce the Behavior

Create a document, section and a table. Clone the table add it to the section. Render the document. An exception will be generated.

spl-sotax commented 9 months ago

I encountered the same issue. I had a different workaround by looping over all tables, their rows and cells and calling ResetCachedValues using reflection. I traced the issue to the DocumentObjectCollection.DeepCopy where the parent is set after the clone. Therefore the cached values are calculated when the parent is not yet set and setting the parent does not trigger resetting the cached values. One possible solution would be to call ResetCachedValues in the setter of Parent.

nicovil commented 8 months ago

I had the same issue, and fixed it like @spl-sotax by modifying or adding ResetCachedValues method at:

In the case of Cell, I had to add a trick that is used in some other places in the Table getter to return table from Parent reference (Parent.Table) when _table is null.

In my case with those minor fixes the table rendering works like a charm.

ThomasHoevel commented 7 months ago

Fixed with PDFsharp 6.1.0 Preview 3, release date not yet known, but coming soon. Thanks for your feedback.