Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Visual Tree Helper (Based on #1820) #1845

Merged
merged 44 commits into from
Jul 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
de1557f
vth
StephaneDelcroix Jul 27, 2021
32bad03
Replace IReadOnlyList<object> with IReadOnlyList<Maui.IElement>
drasticactions Jul 28, 2021
ed5ab3b
Remove unneeded usings
drasticactions Jul 28, 2021
c061c4a
Move interface to Core
drasticactions Jul 28, 2021
0d7279e
Make IVisualTreeHelper Visible to Editor
drasticactions Jul 28, 2021
d7a8d81
Remove IVisualTreeHelper from ItemsView... for now...
drasticactions Jul 28, 2021
174a41a
Make IVisualTreeHelper public
drasticactions Jul 28, 2021
d7cc97d
Update Tests
drasticactions Jul 28, 2021
23d4a9e
Hide IVisualTreeHelper again...
drasticactions Jul 28, 2021
28811af
Put IVisualTreeHelper on IElement
drasticactions Jul 28, 2021
d217b5c
Update Tests
drasticactions Jul 28, 2021
ab09d03
Move properties
drasticactions Jul 29, 2021
ed301ff
Add enter
drasticactions Jul 29, 2021
8449a23
Update stuff
drasticactions Jul 29, 2021
081ec00
Add net6.0 to the projects (#1810)
mattleibow Jul 26, 2021
98e3858
Switch to System.ComponentModel.TypeConverter (#1725)
Redth Jul 26, 2021
bc78b1a
Move New Navigation Handler to Core and make it internal (#1800)
PureWeen Jul 26, 2021
df5993e
[templates] remove Directory.Build.targets, add @(ProjectCapability) …
jonathanpeppers Jul 26, 2021
cef3dcb
Navigation Events (#1812)
PureWeen Jul 27, 2021
eed40bf
Ensure no references to Xamarin.Forms in a .NET Maui app (#1816)
mattleibow Jul 27, 2021
71ed794
[CI] Add NuGet MSI conversion and VS insert stage (#1618)
pjcollins Jul 27, 2021
8903c51
Update layout system to ensure native measure/arrange are called for …
hartez Jul 27, 2021
1693b5e
[workload] support $(UseMaui) from a net6.0 TFM (#1788)
jonathanpeppers Jul 27, 2021
77ac1ab
Update dependencies from https://github.com/xamarin/xamarin-macios bu…
dotnet-maestro[bot] Jul 27, 2021
c6f3fbb
[CI] Only wait 30 minutes for VS insertion task (#1826)
pjcollins Jul 27, 2021
dbaa5cd
Make StaticWebAssets not fail in RCLs referenced by MAUI projects (#1…
Eilon Jul 27, 2021
39a4c55
[main] Update dependencies from xamarin/xamarin-android (#1798)
dotnet-maestro[bot] Jul 27, 2021
e0f60f6
Use the correct variable (#1834)
mattleibow Jul 28, 2021
4b0d5f2
Introduce AutomationProperties.ExcludedWithChildren (#1815)
rachelkang Jul 28, 2021
195257d
Add traits to iOS Checkbox so it reads as Switch (#1832)
PureWeen Jul 28, 2021
7cf0923
Fix traits on Switch so they are settable (#1836)
PureWeen Jul 28, 2021
268cd46
Fix logic for concatenating hints in Android (#1837)
PureWeen Jul 28, 2021
b28e1f4
[main] Update dependencies from xamarin/xamarin-android (#1842)
dotnet-maestro[bot] Jul 28, 2021
bdcef71
Update dependencies from https://github.com/xamarin/xamarin-macios bu…
dotnet-maestro[bot] Jul 28, 2021
5db8bd9
Introduce SetSemanticFocus API via SemanticExtensions (#1829)
PureWeen Jul 28, 2021
ed37c56
Merge fixes from XF 5.0.0 SR4 into MAUI (#1830)
PureWeen Jul 28, 2021
fe6f682
Update static web assets targets
javiercn Jul 28, 2021
7685f18
Update WPF/WinForms to use the new static web assets manifest
javiercn Jul 28, 2021
9c3edee
Swap layout namespaces (#1838)
hartez Jul 29, 2021
64ae1e6
Update dependencies from https://github.com/xamarin/xamarin-android b…
dotnet-maestro[bot] Jul 29, 2021
39a46db
Merge branch 'main' of github.com:drasticactions/maui
drasticactions Jul 29, 2021
5cab002
Merge branch 'main' into dev/timill/vth
drasticactions Jul 29, 2021
fc93140
Fix IVisualTreeElement on Layout
drasticactions Jul 29, 2021
122105e
Add GetVisualParent
drasticactions Jul 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Controls/src/Core/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Microsoft.Maui.Controls
{
public partial class Application : Element, IResourcesProvider, IApplicationController, IElementConfiguration<Application>
public partial class Application : Element, IResourcesProvider, IApplicationController, IElementConfiguration<Application>, IVisualTreeElement
{
readonly WeakEventManager _weakEventManager = new WeakEventManager();
Task<IDictionary<string, object>> _propertiesTask;
Expand Down Expand Up @@ -437,5 +437,7 @@ protected internal virtual void CleanUp()

NavigationProxy = null;
}

IReadOnlyList<Maui.IVisualTreeElement> IVisualTreeElement.GetVisualChildren() => this.Windows;
}
}
6 changes: 5 additions & 1 deletion src/Controls/src/Core/Element.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Microsoft.Maui.Controls
{
public abstract partial class Element : BindableObject, IElement, INameScope, IElementController
public abstract partial class Element : BindableObject, IElement, INameScope, IElementController, IVisualTreeElement
{
public static readonly BindableProperty MenuProperty = BindableProperty.CreateAttached(nameof(Menu), typeof(Menu), typeof(Element), null);

Expand Down Expand Up @@ -319,6 +319,10 @@ public new void SetDynamicResource(BindableProperty property, string key)
base.SetDynamicResource(property, key);
}

IReadOnlyList<Maui.IVisualTreeElement> IVisualTreeElement.GetVisualChildren() => LogicalChildren;

IVisualTreeElement IVisualTreeElement.GetVisualParent() => this.Parent;

protected override void OnBindingContextChanged()
{
this.PropagateBindingContext(LogicalChildrenInternal, (child, bc) =>
Expand Down
2 changes: 2 additions & 0 deletions src/Controls/src/Core/ItemsView.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Maui.Controls.Internals;

Expand Down
4 changes: 3 additions & 1 deletion src/Controls/src/Core/Layout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Size ILayoutManager.ArrangeChildren(Rectangle childBounds)
}
}

public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IFrameworkElement
public abstract class Layout : View, ILayout, ILayoutController, IPaddingElement, IFrameworkElement, IVisualTreeElement
{
public static readonly BindableProperty IsClippedToBoundsProperty =
BindableProperty.Create(nameof(IsClippedToBounds), typeof(bool), typeof(Layout), false);
Expand Down Expand Up @@ -122,6 +122,8 @@ public bool CascadeInputTransparent

public void ForceLayout() => SizeAllocated(Width, Height);

IReadOnlyList<Maui.IVisualTreeElement> IVisualTreeElement.GetVisualChildren() => Children.ToList().AsReadOnly();

[Obsolete("OnSizeRequest is obsolete as of version 2.2.0. Please use OnMeasure instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public sealed override SizeRequest GetSizeRequest(double widthConstraint, double heightConstraint)
Expand Down
5 changes: 4 additions & 1 deletion src/Controls/src/Core/Layout/Layout.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Layouts;

namespace Microsoft.Maui.Controls
{
[ContentProperty(nameof(Children))]
public abstract class Layout : View, Microsoft.Maui.ILayout, IList<IView>, IBindableLayout, IPaddingElement
public abstract class Layout : View, Microsoft.Maui.ILayout, IList<IView>, IBindableLayout, IPaddingElement, IVisualTreeElement
{
protected ILayoutManager _layoutManager;
public ILayoutManager LayoutManager => _layoutManager ??= CreateLayoutManager();
Expand Down Expand Up @@ -152,5 +153,7 @@ Thickness IPaddingElement.PaddingDefaultValueCreator()
{
return new Thickness(0);
}

IReadOnlyList<IVisualTreeElement> IVisualTreeElement.GetVisualChildren() => Children.Cast<IVisualTreeElement>().ToList().AsReadOnly();
}
}
5 changes: 4 additions & 1 deletion src/Controls/src/Core/Shell/ShellContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace Microsoft.Maui.Controls
{
[ContentProperty(nameof(Content))]
public class ShellContent : BaseShellItem, IShellContentController
public class ShellContent : BaseShellItem, IShellContentController, IVisualTreeElement
{
static readonly BindablePropertyKey MenuItemsPropertyKey =
BindableProperty.CreateReadOnly(nameof(MenuItems), typeof(MenuItemCollection), typeof(ShellContent), null,
Expand Down Expand Up @@ -309,5 +309,8 @@ static void ApplyQueryAttributes(object content, IDictionary<string, string> que
}
}
}

IReadOnlyList<Maui.IVisualTreeElement> GetVisualChildren() => new List<Maui.IVisualTreeElement> { ((IShellContentController)this).Page }.AsReadOnly();

}
}
4 changes: 3 additions & 1 deletion src/Controls/src/Core/Shell/ShellItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public TabBar()

[ContentProperty(nameof(Items))]
[EditorBrowsable(EditorBrowsableState.Never)]
public class ShellItem : ShellGroupItem, IShellItemController, IElementConfiguration<ShellItem>, IPropertyPropagationController
public class ShellItem : ShellGroupItem, IShellItemController, IElementConfiguration<ShellItem>, IPropertyPropagationController, IVisualTreeElement
{
#region PropertyKeys

Expand Down Expand Up @@ -310,5 +310,7 @@ internal override void SendDisappearing()
CurrentItem.SendDisappearing();
}
}

IReadOnlyList<Maui.IVisualTreeElement> IVisualTreeElement.GetVisualChildren() => Items.ToList().AsReadOnly();
}
}
4 changes: 3 additions & 1 deletion src/Controls/src/Core/Shell/ShellSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class Tab : ShellSection

[ContentProperty(nameof(Items))]
[EditorBrowsable(EditorBrowsableState.Never)]
public class ShellSection : ShellGroupItem, IShellSectionController, IPropertyPropagationController
public class ShellSection : ShellGroupItem, IShellSectionController, IPropertyPropagationController, IVisualTreeElement
{
#region PropertyKeys

Expand Down Expand Up @@ -1205,5 +1205,7 @@ ShellNavigationState GetUpdatedStatus(IReadOnlyList<Page> stack)
return ShellNavigationManager.GetNavigationState(shellItem, shellSection, shellContent, stack, modalStack);
}
}

IReadOnlyList<Maui.IVisualTreeElement> IVisualTreeElement.GetVisualChildren() => AllChildren.ToList().AsReadOnly();
}
}
12 changes: 12 additions & 0 deletions src/Controls/tests/Core.UnitTests/ShellTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,5 +1318,17 @@ public void SendStructureChangedFiresWhenAddingItems()
Assert.Greater(count, previousCount, "StructureChanged not fired when adding Shell Content");
}

[Test]
public void VisualTreeHelperCount()
{
Shell shell = new Shell();
shell.Items.Add(CreateShellItem());
shell.CurrentItem.Items.Add(CreateShellSection());
shell.CurrentItem.CurrentItem.Items.Add(CreateShellContent());
var shellCount = (shell as IVisualTreeElement).GetVisualChildren();
var shellItemCount = (shell.CurrentItem as IVisualTreeElement).GetVisualChildren();
Assert.AreEqual(shellCount.Count, 1);
Assert.AreEqual(shellItemCount.Count, 2);
}
}
}
74 changes: 74 additions & 0 deletions src/Controls/tests/Core.UnitTests/VisualTreeHelperTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Maui.Graphics;
using NSubstitute;
using NUnit.Framework;

namespace Microsoft.Maui.Controls.Core.UnitTests
{
[TestFixture]
public class VisualTreeHelperTests : BaseTestFixture
{
[Test]
public void VerticalStackLayoutChildren()
{
var verticalStackLayout = new VerticalStackLayout() { IsPlatformEnabled = true };
verticalStackLayout.Children.Add(new Label());
verticalStackLayout.Children.Add(new Button());
Assert.AreEqual(verticalStackLayout.Children.Count, (verticalStackLayout as IVisualTreeElement).GetVisualChildren().Count);
}

[Test]
public void HorizontalStackLayoutChildren()
{
var horizontalStackLayout = new HorizontalStackLayout() { IsPlatformEnabled = true };
horizontalStackLayout.Children.Add(new Label());
horizontalStackLayout.Children.Add(new Button());
Assert.AreEqual(horizontalStackLayout.Children.Count, (horizontalStackLayout as IVisualTreeElement).GetVisualChildren().Count);
}

[Test]
public void StackLayoutChildren()
{
var stackLayout = new StackLayout() { IsPlatformEnabled = true };
stackLayout.Children.Add(new Label());
stackLayout.Children.Add(new Button());
Assert.AreEqual(stackLayout.Children.Count, (stackLayout as IVisualTreeElement).GetVisualChildren().Count);
}

[Test]
public void ApplicationChildren()
{
var app = new Application();
var iapp = app as IApplication;
var page = new ContentPage();

app.MainPage = page;

var window = iapp.CreateWindow(null);

var appChildren = (app as IVisualTreeElement).GetVisualChildren();
var windowChildren = (window as IVisualTreeElement).GetVisualChildren();
Assert.Greater(appChildren.Count, 0);
Assert.IsTrue(appChildren[0] is IWindow);
Assert.AreEqual(windowChildren.Count, 1);
}

[Test]
public void VisualElementParent()
{
var app = new Application();
var iapp = app as IApplication;
var page = new ContentPage();
app.MainPage = page;
var window = iapp.CreateWindow(null);
var appParent = (app as IVisualTreeElement).GetVisualParent();
var windowParent = (window as IVisualTreeElement).GetVisualParent();
Assert.IsNull(appParent);
Assert.IsNotNull(windowParent);
}
}
}
13 changes: 13 additions & 0 deletions src/Core/src/Core/IVisualTreeElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace Microsoft.Maui
{
public interface IVisualTreeElement
{
IReadOnlyList<IVisualTreeElement> GetVisualChildren();

IVisualTreeElement? GetVisualParent();
}
}