Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Avalonia.Controls.TreeDataGrid.sln
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ Global
{9A36E37E-2C03-4B5A-B7EE-A91DC95C3E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A36E37E-2C03-4B5A-B7EE-A91DC95C3E4A}.Release|Any CPU.Build.0 = Release|Any CPU
{D45C7B46-A12C-4412-8397-B51B75A09999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D45C7B46-A12C-4412-8397-B51B75A09999}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D45C7B46-A12C-4412-8397-B51B75A09999}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D45C7B46-A12C-4412-8397-B51B75A09999}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e
EffectiveViewportChanged -= OnEffectiveViewportChanged;

UnsubscribeFromItemChanges();
RecycleAllElements();
}

protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
using System.Linq;
using Avalonia.Collections;
using Avalonia.Controls.Models.TreeDataGrid;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Headless.XUnit;
using Avalonia.LogicalTree;
using Avalonia.Media;
Expand Down Expand Up @@ -423,6 +426,53 @@ public void Handles_Moving_Focused_Row_While_Outside_Viewport()
// The correct element should be shown.
Assert.Same(items[0], target.RealizedElements.ElementAt(0)!.DataContext);
}

[AvaloniaFact(Timeout = 10000)]
public void Handles_Adding_Rows_While_Detached_From_VisualTree()
{
var (target, scroll, items) = CreateTarget(itemCount: 5);
var testWindow = scroll.Parent as TestWindow;

if (testWindow != null)
{
testWindow.Content = null;
testWindow.UpdateLayout();
}

var tabItem = new TabItem { Content = scroll };
var tabControl = new TabControl { Items = { tabItem, new TabItem() }, Template = TabControlTemplate() };

ApplyTemplate(tabControl);

if (testWindow != null)
{
testWindow.Content = tabControl;
tabControl.ApplyTemplate();
testWindow.UpdateLayout();
}

Dispatcher.UIThread.RunJobs();

tabControl.SelectedIndex = 1;

Layout(target);

Enumerable.Range(5, 5).ToList().ForEach(x => items.Insert(1, new Model { Id = x, Title = "Item " + x }));

tabControl.SelectedIndex = 0;
Layout(target);

var indexes = GetRealizedRowIndexes(target);
var models = target!.RealizedElements
.Cast<TreeDataGridRow?>().Select(x => x?.Model)
.Cast<Model>().ToList();

var distinctModelCount = models.DistinctBy(x => x.Id).Count();

Assert.Equal(10, indexes.Count);
Assert.Equal(10, models.Count);
Assert.Equal(10, distinctModelCount);
}

[AvaloniaFact(Timeout = 10000)]
public void Updates_Star_Column_ActualWidth()
Expand Down Expand Up @@ -615,6 +665,55 @@ private static void Layout(TreeDataGridRowsPresenter target)
{
target.UpdateLayout();
}

private static void ApplyTemplate(TabControl target)
{
target.ApplyTemplate();

target.Presenter?.ApplyTemplate();

foreach (var tabItem in target.GetLogicalChildren().OfType<TabItem>())
{
tabItem.Template = TabItemTemplate();

tabItem.ApplyTemplate();

tabItem.Presenter?.UpdateChild();
}
}

private static IControlTemplate TabItemTemplate()
{
return new FuncControlTemplate<TabItem>((parent, scope) =>
new ContentPresenter
{
Name = "PART_ContentPresenter",
[~ContentPresenter.ContentProperty] = new TemplateBinding(TabItem.HeaderProperty),
[~ContentPresenter.ContentTemplateProperty] = new TemplateBinding(TabItem.HeaderTemplateProperty),
RecognizesAccessKey = true,
}.RegisterInNameScope(scope));
}

private static IControlTemplate TabControlTemplate()
{
return new FuncControlTemplate<TabControl>((parent, scope) =>
new StackPanel
{
Children =
{
new ItemsPresenter
{
Name = "PART_ItemsPresenter",
}.RegisterInNameScope(scope),
new ContentPresenter
{
Name = "PART_SelectedContentHost",
[~ContentPresenter.ContentProperty] = new TemplateBinding(TabControl.SelectedContentProperty),
[~ContentPresenter.ContentTemplateProperty] = new TemplateBinding(TabControl.SelectedContentTemplateProperty),
}.RegisterInNameScope(scope)
}
});
}

private class Model
{
Expand Down
Loading