Browse Source

Added ItemsControl.GetRealizedContainers().

Steven Kirk 3 years ago
parent
commit
14d429ec4e

+ 5 - 0
src/Avalonia.Controls/ItemsControl.cs

@@ -211,6 +211,11 @@ namespace Avalonia.Controls
             throw new NotImplementedException();
         }
 
+        /// <summary>
+        /// Gets the currently realized containers.
+        /// </summary>
+        public IEnumerable<Control> GetRealizedContainers() => Presenter?.GetRealizedContainers() ?? Array.Empty<Control>();
+
         /// <inheritdoc/>
         void IItemsPresenterHost.RegisterItemsPresenter(ItemsPresenter presenter)
         {

+ 1 - 10
src/Avalonia.Controls/MenuItem.cs

@@ -328,16 +328,7 @@ namespace Avalonia.Controls
         }
 
         /// <inheritdoc/>
-        IEnumerable<IMenuItem> IMenuElement.SubItems
-        {
-            get
-            {
-                throw new NotImplementedException();
-                ////return ItemContainerGenerator.Containers
-                ////    .Select(x => x.ContainerControl)
-                ////    .OfType<IMenuItem>();
-            }
-        }
+        IEnumerable<IMenuItem> IMenuElement.SubItems => GetRealizedContainers().OfType<IMenuItem>();
 
         /// <summary>
         /// Opens the submenu.

+ 10 - 0
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@@ -1,5 +1,8 @@
 using System;
+using System.Collections;
+using System.Collections.Generic;
 using System.Diagnostics;
+using System.Reflection;
 
 namespace Avalonia.Controls.Presenters
 {
@@ -109,6 +112,13 @@ namespace Avalonia.Controls.Presenters
             return index >= 0 && index < Panel?.Children.Count ? Panel.Children[index] : null;
         }
 
+        internal IEnumerable<Control>? GetRealizedContainers()
+        {
+            if (Panel is VirtualizingPanel v)
+                return v.GetRealizedContainers();
+            return Panel?.Children;
+        }
+
         internal int IndexFromContainer(Control container)
         {
             if (Panel is VirtualizingPanel v)

+ 29 - 30
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@@ -507,45 +507,44 @@ namespace Avalonia.Controls.Primitives
 
         protected override void OnTextInput(TextInputEventArgs e)
         {
-            throw new NotImplementedException();
-            ////if (!e.Handled)
-            ////{
-            ////    if (!IsTextSearchEnabled)
-            ////        return;
+            if (!e.Handled)
+            {
+                if (!IsTextSearchEnabled)
+                    return;
 
-            ////    StopTextSearchTimer();
+                StopTextSearchTimer();
 
-            ////    _textSearchTerm += e.Text;
+                _textSearchTerm += e.Text;
 
-            ////    bool Match(ItemContainerInfo info)
-            ////    {
-            ////        if (info.ContainerControl is AvaloniaObject ao && ao.IsSet(TextSearch.TextProperty))
-            ////        {
-            ////            var searchText = ao.GetValue(TextSearch.TextProperty);
+                bool Match(Control container)
+                {
+                    if (container is AvaloniaObject ao && ao.IsSet(TextSearch.TextProperty))
+                    {
+                        var searchText = ao.GetValue(TextSearch.TextProperty);
 
-            ////            if (searchText?.StartsWith(_textSearchTerm, StringComparison.OrdinalIgnoreCase) == true)
-            ////            {
-            ////                return true;
-            ////            }
-            ////        }
+                        if (searchText?.StartsWith(_textSearchTerm, StringComparison.OrdinalIgnoreCase) == true)
+                        {
+                            return true;
+                        }
+                    }
 
-            ////        return info.ContainerControl is IContentControl control &&
-            ////               control.Content?.ToString()?.StartsWith(_textSearchTerm, StringComparison.OrdinalIgnoreCase) == true;
-            ////    }
-                
-            ////    var info = ItemContainerGenerator?.Containers.FirstOrDefault(Match);
+                    return container is IContentControl control &&
+                           control.Content?.ToString()?.StartsWith(_textSearchTerm, StringComparison.OrdinalIgnoreCase) == true;
+                }
 
-            ////    if (info != null)
-            ////    {
-            ////        SelectedIndex = info.Index;
-            ////    }
+                var container = GetRealizedContainers().FirstOrDefault(Match);
 
-            ////    StartTextSearchTimer();
+                if (container != null)
+                {
+                    SelectedIndex = IndexFromContainer(container);
+                }
 
-            ////    e.Handled = true;
-            ////}
+                StartTextSearchTimer();
+
+                e.Handled = true;
+            }
 
-            ////base.OnTextInput(e);
+            base.OnTextInput(e);
         }
 
         protected override void OnKeyDown(KeyEventArgs e)

+ 6 - 0
src/Avalonia.Controls/VirtualizingPanel.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Diagnostics.CodeAnalysis;
 using Avalonia.Controls.Utils;
@@ -62,6 +63,11 @@ namespace Avalonia.Controls
         /// </returns>
         protected internal abstract int IndexFromContainer(Control container);
 
+        /// <summary>
+        /// Gets the currently realized containers.
+        /// </summary>
+        protected internal abstract IEnumerable<Control>? GetRealizedContainers();
+
         /// <summary>
         /// Gets the next control in the specified direction.
         /// </summary>

+ 6 - 0
src/Avalonia.Controls/VirtualizingStackPanel.cs

@@ -3,6 +3,7 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Diagnostics;
+using System.Linq;
 using Avalonia.Controls.Utils;
 using Avalonia.Input;
 using Avalonia.Layout;
@@ -228,6 +229,11 @@ namespace Avalonia.Controls
             return ScrollIntoView(toIndex);
         }
 
+        protected internal override IEnumerable<Control>? GetRealizedContainers()
+        {
+            return _realizedElements?.Elements.Where(x => x is not null)!;
+        }
+
         protected internal override Control? ContainerFromIndex(int index) => _realizedElements?.GetElement(index);
         protected internal override int IndexFromContainer(Control container) => _realizedElements?.GetIndex(container) ?? -1;
 

+ 12 - 15
tests/Avalonia.LeakTests/ControlTests.cs

@@ -361,8 +361,7 @@ namespace Avalonia.LeakTests
 
                     // Do a layout and make sure that TreeViewItems get realized.
                     window.LayoutManager.ExecuteInitialLayoutPass();
-                    throw new NotImplementedException();
-                    ////Assert.Single(target.ItemContainerGenerator.Containers);
+                    Assert.Single(target.GetRealizedContainers());
 
                     // Clear the content and ensure the TreeView is removed.
                     window.Content = null;
@@ -757,22 +756,20 @@ namespace Avalonia.LeakTests
                 window.Show();
                 window.LayoutManager.ExecuteInitialLayoutPass();
 
-                throw new NotImplementedException();
+                void AssertInitialItemState()
+                {
+                    var item0 = (ListBoxItem)lb.GetRealizedContainers().First();
+                    var canvas0 = (Canvas)item0.Presenter.Child;
+                    Assert.Equal("foo", canvas0.Tag);
+                }
 
-                ////void AssertInitialItemState()
-                ////{
-                ////    var item0 = (ListBoxItem)lb.ItemContainerGenerator.Containers.First().ContainerControl;
-                ////    var canvas0 = (Canvas)item0.Presenter.Child;
-                ////    Assert.Equal("foo", canvas0.Tag);
-                ////}
-               
-                ////Assert.Equal(10, lb.ItemContainerGenerator.Containers.Count());
-                ////AssertInitialItemState();
+                Assert.Equal(10, lb.GetRealizedContainers().Count());
+                AssertInitialItemState();
 
-                ////items.Clear();
-                ////window.LayoutManager.ExecuteLayoutPass();
+                items.Clear();
+                window.LayoutManager.ExecuteLayoutPass();
 
-                ////Assert.Empty(lb.ItemContainerGenerator.Containers);
+                Assert.Empty(lb.GetRealizedContainers());
 
                 // Process all Loaded events to free control reference(s)
                 Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded);