Kaynağa Gözat

#1802 add SelectedItemChanged event to TreeView

Jeffrey Ye 7 yıl önce
ebeveyn
işleme
e9cde299bb

+ 36 - 0
src/Avalonia.Controls/SelectedItemChangedEventArgs.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using Avalonia;
+using Avalonia.Interactivity;
+
+namespace Avalonia.Controls
+{
+    /// <summary>
+    /// Provides data for the <see cref="TreeView.SelectedItemChanged"/> event.
+    /// </summary>
+    public class SelectedItemChangedEventArgs : RoutedEventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SelectedItemChangedEventArgs"/> class.
+        /// </summary>
+        /// <param name="routedEvent">The event being raised.</param>
+        /// <param name="newItem">The items added to the selection.</param>
+        /// <param name="oldItem">The items removed from the selection.</param>
+        public SelectedItemChangedEventArgs(RoutedEvent routedEvent, object newItem, object oldItem)
+                : base(routedEvent)
+        {
+            NewItem = newItem;
+            OldItem = oldItem;
+        }
+
+        /// <summary>
+        /// Gets the items that were added to the selection.
+        /// </summary>
+        public object NewItem { get; }
+
+        /// <summary>
+        /// Gets the items that were removed from the selection.
+        /// </summary>
+        public object OldItem { get; }
+    }
+}

+ 27 - 0
src/Avalonia.Controls/TreeView.cs

@@ -32,6 +32,14 @@ namespace Avalonia.Controls
                 o => o.SelectedItem,
                 (o, v) => o.SelectedItem = v);
 
+        /// <summary>
+        /// Defines the <see cref="SelectedItemChanged"/> event.
+        /// </summary>
+        public static readonly RoutedEvent<SelectedItemChangedEventArgs> SelectedItemChangedEvent =
+            RoutedEvent.Register<TreeView, SelectedItemChangedEventArgs>(
+                "SelectedItemChanged",
+                RoutingStrategies.Bubble);
+
         private object _selectedItem;
 
         /// <summary>
@@ -42,6 +50,15 @@ namespace Avalonia.Controls
             // HACK: Needed or SelectedItem property will not be found in Release build.
         }
 
+        /// <summary>
+        /// Occurs when the control's selection changes.
+        /// </summary>
+        public event EventHandler<SelectedItemChangedEventArgs> SelectedItemChanged
+        {
+            add { AddHandler(SelectedItemChangedEvent, value); }
+            remove { RemoveHandler(SelectedItemChangedEvent, value); }
+        }
+
         /// <summary>
         /// Gets the <see cref="ITreeItemContainerGenerator"/> for the tree view.
         /// </summary>
@@ -75,6 +92,7 @@ namespace Avalonia.Controls
                     MarkContainerSelected(container, false);
                 }
 
+                var oldItem = _selectedItem;
                 SetAndRaise(SelectedItemProperty, ref _selectedItem, value);
 
                 if (_selectedItem != null)
@@ -87,6 +105,15 @@ namespace Avalonia.Controls
                         container.BringIntoView();
                     }
                 }
+
+                if (oldItem != _selectedItem)
+                {
+                    var changed = new SelectedItemChangedEventArgs(
+                        SelectedItemChangedEvent,
+                        _selectedItem,
+                        oldItem);
+                    RaiseEvent(changed);
+                }
             }
         }
 

+ 32 - 0
tests/Avalonia.Controls.UnitTests/TreeViewTests.cs

@@ -166,6 +166,38 @@ 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.Null(e.OldItem);
+                Assert.Same(item, e.NewItem);
+                called = true;
+            };
+
+            target.SelectedItem = item;
+            Assert.True(called);
+        }
+
+
         [Fact]
         public void LogicalChildren_Should_Be_Set()
         {