Skip to content

Commit

Permalink
Merge pull request #6854 from gabornemeth/treeview_custom_items
Browse files Browse the repository at this point in the history
type of the TreeView's items can be customized
  • Loading branch information
grokys authored Dec 6, 2021
2 parents 6798e20 + b595a03 commit e185e07
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 8 deletions.
14 changes: 11 additions & 3 deletions src/Avalonia.Controls/TreeView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,14 +392,22 @@ private void UnsubscribeFromSelectedItems()
/// <inheritdoc/>
protected override IItemContainerGenerator CreateItemContainerGenerator()
{
var result = new TreeItemContainerGenerator<TreeViewItem>(
var result = CreateTreeItemContainerGenerator();
result.Index.Materialized += ContainerMaterialized;
return result;
}

protected virtual ITreeItemContainerGenerator CreateTreeItemContainerGenerator() =>
CreateTreeItemContainerGenerator<TreeViewItem>();

protected virtual ITreeItemContainerGenerator CreateTreeItemContainerGenerator<TVItem>() where TVItem: TreeViewItem, new()
{
return new TreeItemContainerGenerator<TVItem>(
this,
TreeViewItem.HeaderProperty,
TreeViewItem.ItemTemplateProperty,
TreeViewItem.ItemsProperty,
TreeViewItem.IsExpandedProperty);
result.Index.Materialized += ContainerMaterialized;
return result;
}

/// <inheritdoc/>
Expand Down
8 changes: 6 additions & 2 deletions src/Avalonia.Controls/TreeViewItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,13 @@ public int Level
(ITreeItemContainerGenerator)base.ItemContainerGenerator;

/// <inheritdoc/>
protected override IItemContainerGenerator CreateItemContainerGenerator()
protected override IItemContainerGenerator CreateItemContainerGenerator() => CreateTreeItemContainerGenerator<TreeViewItem>();

/// <inheritdoc/>
protected virtual ITreeItemContainerGenerator CreateTreeItemContainerGenerator<TVItem>()
where TVItem: TreeViewItem, new()
{
return new TreeItemContainerGenerator<TreeViewItem>(
return new TreeItemContainerGenerator<TVItem>(
this,
TreeViewItem.HeaderProperty,
TreeViewItem.ItemTemplateProperty,
Expand Down
46 changes: 43 additions & 3 deletions tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Runtime.CompilerServices;
using Avalonia.Collections;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
Expand All @@ -24,7 +25,7 @@ namespace Avalonia.Controls.UnitTests
public class TreeViewTests
{
MouseTestHelper _mouse = new MouseTestHelper();

[Fact]
public void Items_Should_Be_Created()
{
Expand Down Expand Up @@ -675,7 +676,7 @@ public void Keyboard_Navigation_Should_Move_To_Last_Selected_Node()
Assert.Same(node, focus.Current);
}
}

[Fact]
public void Keyboard_Navigation_Should_Not_Crash_If_Selected_Item_Is_not_In_Tree()
{
Expand Down Expand Up @@ -1166,6 +1167,34 @@ public void Clearing_TreeView_Items_Clears_Index()
Assert.Empty(target.ItemContainerGenerator.Index.Containers);
}

[Fact]
public void Can_Use_Derived_TreeViewItem()
{
var tree = CreateTestTreeData();
var target = new DerivedTreeViewWithDerivedTreeViewItems
{
Template = CreateTreeViewTemplate(),
Items = tree,
};

ApplyTemplates(target);

// Verify that all items are DerivedTreeViewItem
VerifyItemType(target.ItemContainerGenerator);

void VerifyItemType(ITreeItemContainerGenerator containerGenerator)
{
foreach (var container in containerGenerator.Index.Containers)
{
var item = Assert.IsType<DerivedTreeViewItem>(container);
if (item.ItemCount > 0)
{
VerifyItemType(item.ItemContainerGenerator);
}
}
}
}

private void ApplyTemplates(TreeView tree)
{
tree.ApplyTemplate();
Expand Down Expand Up @@ -1376,6 +1405,17 @@ private class DerivedTreeView : TreeView
{
}

private class DerivedTreeViewWithDerivedTreeViewItems : TreeView
{
protected override ITreeItemContainerGenerator CreateTreeItemContainerGenerator() =>
CreateTreeItemContainerGenerator<DerivedTreeViewItem>();
}

private class DerivedTreeViewItem : TreeViewItem
{
protected override IItemContainerGenerator CreateItemContainerGenerator() => CreateTreeItemContainerGenerator<DerivedTreeViewItem>();
}

private class TestDataContext : INotifyPropertyChanged
{
private string _selectedItem;
Expand All @@ -1398,7 +1438,7 @@ public string SelectedItem
}

public event PropertyChangedEventHandler PropertyChanged;

}
}
}

0 comments on commit e185e07

Please sign in to comment.