diff --git a/src/Avalonia.Controls/TreeView.cs b/src/Avalonia.Controls/TreeView.cs index 3003dab85e..c574799724 100644 --- a/src/Avalonia.Controls/TreeView.cs +++ b/src/Avalonia.Controls/TreeView.cs @@ -1,6 +1,8 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; +using System.Collections.Generic; using System.Linq; using Avalonia.Controls.Generators; using Avalonia.Controls.Primitives; @@ -31,6 +33,14 @@ namespace Avalonia.Controls o => o.SelectedItem, (o, v) => o.SelectedItem = v); + /// + /// Defines the event. + /// + public static readonly RoutedEvent SelectedItemChangedEvent = + RoutedEvent.Register( + "SelectedItemChanged", + RoutingStrategies.Bubble); + private object _selectedItem; /// @@ -41,6 +51,15 @@ namespace Avalonia.Controls // HACK: Needed or SelectedItem property will not be found in Release build. } + /// + /// Occurs when the control's selection changes. + /// + public event EventHandler SelectedItemChanged + { + add { AddHandler(SelectedItemChangedEvent, value); } + remove { RemoveHandler(SelectedItemChangedEvent, value); } + } + /// /// Gets the for the tree view. /// @@ -74,6 +93,7 @@ namespace Avalonia.Controls MarkContainerSelected(container, false); } + var oldItem = _selectedItem; SetAndRaise(SelectedItemProperty, ref _selectedItem, value); if (_selectedItem != null) @@ -86,6 +106,28 @@ namespace Avalonia.Controls container.BringIntoView(); } } + + if (oldItem != _selectedItem) + { + // Fire the SelectionChanged event + List removed = new List(); + if (oldItem != null) + { + removed.Add(oldItem); + } + + List added = new List(); + if (_selectedItem != null) + { + added.Add(_selectedItem); + } + + var changed = new SelectionChangedEventArgs( + SelectedItemChangedEvent, + added, + removed); + RaiseEvent(changed); + } } } diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs index c49c343a45..1a913865cb 100644 --- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs @@ -166,6 +166,39 @@ namespace Avalonia.Controls.UnitTests Assert.True(container.IsSelected); } + + [Fact] + public void Setting_SelectedItem_Should_Raise_SelectedItemChanged_Event() + { + var tree = CreateTestTreeData(); + var target = new TreeView + { + Template = CreateTreeViewTemplate(), + Items = tree, + }; + + var visualRoot = new TestRoot(); + visualRoot.Child = target; + + CreateNodeDataTemplate(target); + ApplyTemplates(target); + + var item = tree[0].Children[1].Children[0]; + + var called = false; + target.SelectedItemChanged += (s, e) => + { + Assert.Empty(e.RemovedItems); + Assert.Equal(1, e.AddedItems.Count); + Assert.Same(item, e.AddedItems[0]); + called = true; + }; + + target.SelectedItem = item; + Assert.True(called); + } + + [Fact] public void LogicalChildren_Should_Be_Set() {