diff --git a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs index 2e4a1a4828..4662d2532e 100644 --- a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs +++ b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs @@ -34,7 +34,7 @@ namespace Avalonia.Controls.Primitives if (visual is TopLevel topLevel) { - manager = topLevel.GetTemplateChildren() + manager = topLevel.GetTemplateDescendants() .OfType() .FirstOrDefault(); } diff --git a/src/Avalonia.Controls/Primitives/TemplatedControl.cs b/src/Avalonia.Controls/Primitives/TemplatedControl.cs index d8ecfa99e8..80f4aa572e 100644 --- a/src/Avalonia.Controls/Primitives/TemplatedControl.cs +++ b/src/Avalonia.Controls/Primitives/TemplatedControl.cs @@ -317,7 +317,7 @@ namespace Avalonia.Controls.Primitives { if (VisualChildren.Count > 0) { - foreach (var child in this.GetTemplateChildren()) + foreach (var child in this.GetTemplateDescendants()) { child.TemplatedParent = null; ((ISetLogicalParent)child).SetParent(null); @@ -350,11 +350,11 @@ namespace Avalonia.Controls.Primitives /// protected override Control GetTemplateFocusTarget() { - foreach (Control child in this.GetTemplateChildren()) + foreach (var child in this.GetTemplateDescendants()) { - if (GetIsTemplateFocusTarget(child)) + if (child is Control control && GetIsTemplateFocusTarget(control)) { - return child; + return control; } } diff --git a/src/Avalonia.Controls/Templates/TemplateExtensions.cs b/src/Avalonia.Controls/Templates/TemplateExtensions.cs index b8d90ae458..6d10244ba4 100644 --- a/src/Avalonia.Controls/Templates/TemplateExtensions.cs +++ b/src/Avalonia.Controls/Templates/TemplateExtensions.cs @@ -1,26 +1,47 @@ using System; using System.Collections.Generic; -using System.Linq; -using Avalonia.Controls; using Avalonia.Controls.Primitives; -using Avalonia.Styling; using Avalonia.VisualTree; namespace Avalonia.Controls.Templates { + /// + /// Contains extension methods for . + /// public static class TemplateExtensions { + /// + /// Gets the list of all control descendants that are part of the template of a , + /// i.e. their is . + /// + /// The control whose descendants will be returned. + /// An enumeration of objects. + [Obsolete($"Use {nameof(GetTemplateDescendants)}")] public static IEnumerable GetTemplateChildren(this TemplatedControl control) { - foreach (Control child in GetTemplateChildren(control, control)) + foreach (var child in control.GetTemplateDescendants()) { - yield return child; + if (child is Control childControl) + { + yield return childControl; + } } } - private static IEnumerable GetTemplateChildren(Control control, TemplatedControl templatedParent) + /// + /// Gets the list of all visual descendants that are part of the template of a , + /// i.e. their is . + /// + /// The control whose descendants will be returned. + /// An enumeration of objects. + public static IEnumerable GetTemplateDescendants(this TemplatedControl control) + { + return GetTemplateDescendants(control, control); + } + + private static IEnumerable GetTemplateDescendants(Visual control, TemplatedControl templatedParent) { - foreach (Control child in control.GetVisualChildren()) + foreach (var child in control.GetVisualChildren()) { var childTemplatedParent = child.TemplatedParent; @@ -31,7 +52,7 @@ namespace Avalonia.Controls.Templates if (childTemplatedParent != null) { - foreach (var descendant in GetTemplateChildren(child, templatedParent)) + foreach (var descendant in GetTemplateDescendants(child, templatedParent)) { yield return descendant; } diff --git a/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs b/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs index 4922fbe37b..2daedca80c 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/FullLayoutTests.cs @@ -86,8 +86,8 @@ namespace Avalonia.Base.UnitTests.Layout Assert.Equal(new Point(300, 200), Position(scrollViewer)); Assert.Equal(new Size(400, 400), textBlock.Bounds.Size); - var scrollBars = scrollViewer.GetTemplateChildren().OfType().ToList(); - var presenters = scrollViewer.GetTemplateChildren().OfType().ToList(); + var scrollBars = scrollViewer.GetTemplateDescendants().OfType().ToList(); + var presenters = scrollViewer.GetTemplateDescendants().OfType().ToList(); Assert.Equal(2, scrollBars.Count); Assert.Single(presenters); diff --git a/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs b/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs index 3bdec3bc7e..4232624fad 100644 --- a/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs @@ -1235,7 +1235,7 @@ namespace Avalonia.Controls.UnitTests } private TextBox GetTextBox(AutoCompleteBox control) { - return control.GetTemplateChildren() + return control.GetTemplateDescendants() .OfType() .First(); } diff --git a/tests/Avalonia.Controls.UnitTests/CalendarDatePickerTests.cs b/tests/Avalonia.Controls.UnitTests/CalendarDatePickerTests.cs index d97a9729fb..b620601f71 100644 --- a/tests/Avalonia.Controls.UnitTests/CalendarDatePickerTests.cs +++ b/tests/Avalonia.Controls.UnitTests/CalendarDatePickerTests.cs @@ -155,7 +155,7 @@ namespace Avalonia.Controls.UnitTests private TextBox GetTextBox(CalendarDatePicker control) { - return control.GetTemplateChildren() + return control.GetTemplateDescendants() .OfType() .First(); } diff --git a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs index 578484557f..b3212ed0f7 100644 --- a/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs @@ -834,7 +834,7 @@ namespace Avalonia.Controls.UnitTests target.ApplyTemplate(); target.Presenter!.ApplyTemplate(); - var containerPanel = target.GetTemplateChildren().OfType().FirstOrDefault(x => x.Name == "container"); + var containerPanel = target.GetTemplateDescendants().OfType().FirstOrDefault(x => x.Name == "container"); var editableTextBox = containerPanel?.GetVisualDescendants().OfType().FirstOrDefault(x => x.Name == "PART_EditableTextBox"); var popup = containerPanel?.GetVisualDescendants().OfType().FirstOrDefault(x => x.Name == "PART_Popup"); var popupScrollViewer = popup?.Child as ScrollViewer; diff --git a/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs b/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs index e368d93892..a7996a46ca 100644 --- a/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs +++ b/tests/Avalonia.Controls.UnitTests/CommandBarTests.cs @@ -495,7 +495,7 @@ public class CommandBarDefaultsTests : ScopedTestBase command.ApplyStyling(); command.ApplyTemplate(); - var presenter = command.GetTemplateChildren() + var presenter = command.GetTemplateDescendants() .OfType() .Single(x => x.Name == "PART_IconPresenter"); diff --git a/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs b/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs index 30d789f08f..87eb4ef2af 100644 --- a/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ContentControlTests.cs @@ -57,7 +57,7 @@ namespace Avalonia.Controls.UnitTests target.ApplyTemplate(); target.Presenter!.ApplyTemplate(); - foreach (Control child in target.GetTemplateChildren()) + foreach (var child in target.GetTemplateDescendants().OfType()) Assert.Equal("foo", child.Tag); } diff --git a/tests/Avalonia.Controls.UnitTests/NumericUpDownTests.cs b/tests/Avalonia.Controls.UnitTests/NumericUpDownTests.cs index 868b33d7bd..b1a402435d 100644 --- a/tests/Avalonia.Controls.UnitTests/NumericUpDownTests.cs +++ b/tests/Avalonia.Controls.UnitTests/NumericUpDownTests.cs @@ -142,7 +142,7 @@ namespace Avalonia.Controls.UnitTests } private static TextBox GetTextBox(NumericUpDown control) { - return control.GetTemplateChildren() + return control.GetTemplateDescendants() .OfType() .Select(b => b.Content) .OfType() @@ -151,7 +151,7 @@ namespace Avalonia.Controls.UnitTests private static ButtonSpinner GetSpinner(NumericUpDown control) { - return control.GetTemplateChildren() + return control.GetTemplateDescendants() .OfType() .First(); } diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs index ca38a56166..dcf9b6f653 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs @@ -329,7 +329,7 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - var popup = (Popup)target.GetTemplateChildren().First(x => x.Name == "popup"); + var popup = (Popup)target.GetTemplateDescendants().First(x => x.Name == "popup"); popup.Open(); var popupRoot = (Control)popup.Host!; @@ -420,7 +420,7 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - var popup = (Popup)target.GetTemplateChildren().First(x => x.Name == "popup"); + var popup = (Popup)target.GetTemplateDescendants().First(x => x.Name == "popup"); popup.Open(); var popupRoot = (Control)popup.Host!; @@ -515,7 +515,7 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - var popup = (Popup)target.GetTemplateChildren().First(x => x.Name == "popup"); + var popup = (Popup)target.GetTemplateDescendants().First(x => x.Name == "popup"); popup.Open(); var popupRoot = (Control)popup.Host!; diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs index 215cdb64b3..b6bfab09cc 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs @@ -20,7 +20,7 @@ namespace Avalonia.Controls.UnitTests.Primitives }; target.ApplyTemplate(); - var track = (Track)target.GetTemplateChildren().First(x => x.Name == "track"); + var track = (Track)target.GetTemplateDescendants().First(x => x.Name == "track"); target.Value = 50; Assert.Equal(50, track.Value); @@ -35,7 +35,7 @@ namespace Avalonia.Controls.UnitTests.Primitives }; target.ApplyTemplate(); - var track = (Track)target.GetTemplateChildren().First(x => x.Name == "track"); + var track = (Track)target.GetTemplateDescendants().First(x => x.Name == "track"); track.Value = 50; Assert.Equal(50, target.Value); @@ -51,7 +51,7 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - var track = (Track)target.GetTemplateChildren().First(x => x.Name == "track"); + var track = (Track)target.GetTemplateDescendants().First(x => x.Name == "track"); target.Value = 25; track.Value = 50; @@ -68,7 +68,7 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - var track = (Track)target.GetTemplateChildren().First(x => x.Name == "track"); + var track = (Track)target.GetTemplateDescendants().First(x => x.Name == "track"); var raisedEvent = Assert.Raises( handler => target.Scroll += handler, @@ -97,7 +97,7 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - var track = (Track)target.GetTemplateChildren().First(x => x.Name == "track"); + var track = (Track)target.GetTemplateDescendants().First(x => x.Name == "track"); var raisedEvent = Assert.Raises( handler => target.Scroll += handler, diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs index 721ad45c11..8a35a75dc4 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs @@ -204,7 +204,7 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - foreach (Control child in target.GetTemplateChildren()) + foreach (var child in target.GetTemplateDescendants().OfType()) Assert.Equal("foo", child.Tag); } @@ -237,11 +237,11 @@ namespace Avalonia.Controls.UnitTests.Primitives target.ApplyTemplate(); - var contentControl = target.GetTemplateChildren().OfType().Single(); + var contentControl = target.GetTemplateDescendants().OfType().Single(); contentControl.ApplyTemplate(); - var border = contentControl.GetTemplateChildren().OfType().Single(); - var presenter = contentControl.GetTemplateChildren().OfType().Single(); + var border = contentControl.GetTemplateDescendants().OfType().Single(); + var presenter = contentControl.GetTemplateDescendants().OfType().Single(); var decorator = (Decorator)presenter.Content!; var textBlock = (TextBlock)decorator.Child!; diff --git a/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs b/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs index e71f4bd8b7..ec1cd5fb66 100644 --- a/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs @@ -610,9 +610,9 @@ namespace Avalonia.Controls.UnitTests private Thumb GetVerticalThumb(ScrollViewer target) { var scrollbar = Assert.IsType( - target.GetTemplateChildren().FirstOrDefault(x => x.Name == "PART_VerticalScrollBar")); + target.GetTemplateDescendants().FirstOrDefault(x => x.Name == "PART_VerticalScrollBar")); var track = Assert.IsType( - scrollbar.GetTemplateChildren().FirstOrDefault(x => x.Name == "track")); + scrollbar.GetTemplateDescendants().FirstOrDefault(x => x.Name == "track")); return Assert.IsType(track.Thumb); } diff --git a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs index 06a7054766..ea14eb5b2f 100644 --- a/tests/Avalonia.Controls.UnitTests/TabControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TabControlTests.cs @@ -1701,7 +1701,7 @@ namespace Avalonia.Controls.UnitTests tabItem.ApplyTemplate(); tabItem.Presenter!.UpdateChild(); - var iconPresenter = tabItem.GetTemplateChildren().OfType().First(x => x.Name == "PART_IconPresenter"); + var iconPresenter = tabItem.GetTemplateDescendants().OfType().First(x => x.Name == "PART_IconPresenter"); Assert.NotNull(iconPresenter); Assert.Equal("home", iconPresenter!.Content); Assert.NotNull(iconPresenter.ContentTemplate); @@ -1729,7 +1729,7 @@ namespace Avalonia.Controls.UnitTests tabItem.ApplyTemplate(); tabItem.Presenter!.UpdateChild(); - var iconPresenter = tabItem.GetTemplateChildren().OfType().First(x => x.Name == "PART_IconPresenter"); + var iconPresenter = tabItem.GetTemplateDescendants().OfType().First(x => x.Name == "PART_IconPresenter"); Assert.NotNull(iconPresenter); Assert.Same(icon, iconPresenter!.Content); Assert.Null(iconPresenter.ContentTemplate); @@ -1748,7 +1748,7 @@ namespace Avalonia.Controls.UnitTests tabItem.ApplyTemplate(); tabItem.Presenter!.UpdateChild(); - var iconPresenter = tabItem.GetTemplateChildren().OfType().First(x => x.Name == "PART_IconPresenter"); + var iconPresenter = tabItem.GetTemplateDescendants().OfType().First(x => x.Name == "PART_IconPresenter"); Assert.Equal("first", iconPresenter!.Content); tabItem.Icon = "second"; diff --git a/tests/Avalonia.Controls.UnitTests/Templates/TemplateExtensionsTests.cs b/tests/Avalonia.Controls.UnitTests/Templates/TemplateExtensionsTests.cs index d540ae9444..734c2a916d 100644 --- a/tests/Avalonia.Controls.UnitTests/Templates/TemplateExtensionsTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Templates/TemplateExtensionsTests.cs @@ -38,7 +38,7 @@ namespace Avalonia.Controls.Templates.UnitTests border3.Child = border4; border4.Child = border5; - var result = target.GetTemplateChildren().Select(x => x.Name).ToArray(); + var result = target.GetTemplateDescendants().Select(x => x.Name).ToArray(); Assert.Equal(new[] { "border1", "inner", "border4" }, result); } diff --git a/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs b/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs index b84fef1fb2..7f42e20307 100644 --- a/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs @@ -371,7 +371,7 @@ namespace Avalonia.Controls.UnitTests private static ContentPresenter GetContentPresenters2(TransitioningContentControl target) { return Assert.IsType(target - .GetTemplateChildren() + .GetTemplateDescendants() .First(x => x.Name == "PART_ContentPresenter2")); } diff --git a/tests/Avalonia.LeakTests/ControlTests.cs b/tests/Avalonia.LeakTests/ControlTests.cs index 33edc0d00d..108ba2c5f4 100644 --- a/tests/Avalonia.LeakTests/ControlTests.cs +++ b/tests/Avalonia.LeakTests/ControlTests.cs @@ -251,7 +251,7 @@ namespace Avalonia.LeakTests Assert.Same(textBox, window.Presenter!.Child); // Get the border from the TextBox template. - var border = textBox.GetTemplateChildren().FirstOrDefault(x => x.Name == "border"); + var border = textBox.GetTemplateDescendants().FirstOrDefault(x => x.Name == "border"); // The TextBox should have subscriptions to its Classes collection from the // default theme. diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs index b6cd86c563..1f2dcff0b7 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_TemplatedParent.cs @@ -67,7 +67,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Data window.ApplyTemplate(); button.ApplyTemplate(); - Assert.Equal(button.Tag, button.GetTemplateChildren().OfType().First().ColumnDefinitions[0].Width); + Assert.Equal(button.Tag, button.GetTemplateDescendants().OfType().First().ColumnDefinitions[0].Width); } } } diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs index 727b3ddc45..99a79ded75 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs @@ -1011,7 +1011,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions contentControl.DataContext = new TestDataContext(); // should be ignored contentControl.Measure(new Size(10, 10)); - var result = contentControl.GetTemplateChildren().OfType().First(); + var result = contentControl.GetTemplateDescendants().OfType().First(); Assert.Equal(false, result.Focusable); } } @@ -1046,7 +1046,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions textBox.DataContext = new TestDataContext(); // should be ignored textBox.Measure(new Size(10, 10)); - var result = textBox.GetTemplateChildren().OfType().First(); + var result = textBox.GetTemplateDescendants().OfType().First(); Assert.Equal(textBox.InnerLeftContent, result.Content); } } @@ -1080,7 +1080,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions window.ApplyTemplate(); button.ApplyTemplate(); - Assert.Equal(button.Tag, button.GetTemplateChildren().OfType().First().ColumnDefinitions[0].Width); + Assert.Equal(button.Tag, button.GetTemplateDescendants().OfType().First().ColumnDefinitions[0].Width); } } @@ -1109,7 +1109,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions var contentControl = AvaloniaRuntimeXamlLoader.Parse(xaml); contentControl.Measure(new Size(10, 10)); - var result = contentControl.GetTemplateChildren().OfType().First(); + var result = contentControl.GetTemplateDescendants().OfType().First(); Assert.Equal("Hello", result.Content); }