Open wieslawsoltes opened 4 months ago
Same issue
Tested it can reproed also in 11.0.0 and 11.0.1
Tested 11.0.0-preview1 and seems to be working properly
Actually even without min/max width the layout breaks when scrolling.
repro:
Columns =
{
new TextColumn<Country, string>("Country", x => x.Name, (r, v) => r.Name = v, new GridLength(1, GridUnitType.Star), new()
{
IsTextSearchEnabled = true,
}),
new TemplateColumn<Country>("Region", "RegionCell", "RegionEditCell"),
new TextColumn<Country, int>("Population", x => x.Population, new GridLength(200, GridUnitType.Auto), new TextColumnOptions<Country>() ),
new TextColumn<Country, int>("Area", x => x.Area, new GridLength(200, GridUnitType.Auto), new TextColumnOptions<Country>() ),
new TextColumn<Country, int>("GDP", x => x.GDP, new GridLength(200, GridUnitType.Auto), new()
{
TextAlignment = Avalonia.Media.TextAlignment.Right,
}),
}
screenshots:
@wieslawsoltes, Isn't it something with the RealizeElements function inside TreeDataGridPresenterBase? Is it really related to viewport?
Seems to be related to this:
At least, I've tried to catch those problematic rows, but dont know what to do with them exactly and how to update them properly... Does it make sense?
private void RealizeElements(
IReadOnlyList<TItem> items,
Size availableSize,
ref MeasureViewport viewport)
{
Debug.Assert(_measureElements is not null);
Debug.Assert(_realizedElements is not null);
Debug.Assert(items.Count > 0);
var index = viewport.anchorIndex;
var horizontal = Orientation == Orientation.Horizontal;
var u = viewport.anchorU;
// If the anchor element is at the beginning of, or before, the start of the viewport
// then we can recycle all elements before it.
if (u <= viewport.anchorU)
_realizedElements.RecycleElementsBefore(viewport.anchorIndex, _recycleElement);
// Start at the anchor element and move forwards, realizing elements.
do
{
var e = GetOrCreateElement(items, index);
var constraint = GetInitialConstraint(e, index, availableSize);
var slot = MeasureElement(index, e, constraint);
var sizeU = horizontal ? slot.Width : slot.Height;
var sizeV = horizontal ? slot.Height : slot.Width;
_measureElements!.Add(index, e, u, sizeU);
//viewport.measuredV = Math.Max(viewport.measuredV, sizeV);
if (horizontal == false && items.GetType() == typeof(AnonymousSortableRows<DataRowView>))
{
if (sizeV - viewport.measuredV == sizeV)
viewport.measuredV = Math.Max(viewport.measuredV, sizeV);
else
{
if (viewport.measuredV != sizeV)
if (Math.Abs(sizeV - viewport.measuredV) <= 200 || Math.Abs(sizeV - viewport.measuredV) > 200)
{
if (sizeV > viewport.measuredV)
{
sizeV = viewport.measuredV;
e.Arrange(new Rect(e.Bounds.Left, e.Bounds.Top, viewport.measuredV, sizeU));
e.Measure(e.Bounds.Size);
} else
{
viewport.measuredV = sizeV;
e.Arrange(new Rect(e.Bounds.Left, e.Bounds.Top, viewport.measuredV, sizeU));
e.Measure(e.Bounds.Size);
}
}
else if (viewport.measuredV == sizeV)
{
}
}
}
else
viewport.measuredV = Math.Max(viewport.measuredV, sizeV);
u += sizeU;
++index;
} while (u < viewport.viewportUEnd && index < items.Count);
// Store the last index and end U position for the desired size calculation.
viewport.lastIndex = index - 1;
viewport.realizedEndU = u;
// We can now recycle elements after the last element.
_realizedElements.RecycleElementsAfter(viewport.lastIndex, _recycleElement);
// Next move backwards from the anchor element, realizing elements.
index = viewport.anchorIndex - 1;
u = viewport.anchorU;
while (u > viewport.viewportUStart && index >= 0)
{
var e = GetOrCreateElement(items, index);
var constraint = GetInitialConstraint(e, index, availableSize);
var slot = MeasureElement(index, e, constraint);
var sizeU = horizontal ? slot.Width : slot.Height;
var sizeV = horizontal ? slot.Height : slot.Width;
u -= sizeU;
_measureElements.Add(index, e, u, sizeU);
//viewport.measuredV = Math.Max(viewport.measuredV, sizeV);
if (horizontal == false && items.GetType() == typeof(AnonymousSortableRows<DataRowView>))
{
if (sizeV - viewport.measuredV == sizeV)
viewport.measuredV = Math.Max(viewport.measuredV, sizeV);
else
{
if (viewport.measuredV != sizeV)
if (Math.Abs(sizeV - viewport.measuredV) <= 200 || Math.Abs(sizeV - viewport.measuredV) > 200)
{
if (sizeV > viewport.measuredV)
{
sizeV = viewport.measuredV;
e.Arrange(new Rect(e.Bounds.Left, e.Bounds.Top, viewport.measuredV, sizeU));
e.Measure(e.Bounds.Size);
}
else
{
viewport.measuredV = sizeV;
e.Arrange(new Rect(e.Bounds.Left, e.Bounds.Top, viewport.measuredV, sizeU));
e.Measure(e.Bounds.Size);
}
}
else if (viewport.measuredV == sizeV)
{
}
}
}
else
viewport.measuredV = Math.Max(viewport.measuredV, sizeV);
--index;
}
// We can now recycle elements before the first element.
_realizedElements.RecycleElementsBefore(index + 1, _recycleElement);
}
Also, I've noticed when columns have equal widths there's no bug at all, and when I change width manually it happens.
The sorting operation also triggers this bug, hopefully it will be fixed sooner!
Repro