Skip to content

Commit

Permalink
fix: Adjust TreeHelper to correctly handle native elements
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Oct 5, 2024
1 parent 27b8448 commit 06e9137
Showing 1 changed file with 103 additions and 101 deletions.
204 changes: 103 additions & 101 deletions src/Uno.UI.RuntimeTests/MUX/Helpers/TreeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,146 +6,148 @@
using Microsoft.UI.Xaml.Documents;
using Microsoft.UI.Xaml.Media;

namespace Uno.UI.RuntimeTests.MUX.Helpers
namespace Uno.UI.RuntimeTests.MUX.Helpers;

// Uno specific: Most of these methods are now taking DependencyObject parameter instead of FrameworkElement
// to handle native elements like NativeScrollContentPresenter.

internal static class TreeHelper
{
internal static class TreeHelper
public static FrameworkElement GetVisualChildByName(DependencyObject parent, string name)
{
public static FrameworkElement GetVisualChildByName(FrameworkElement parent, string name)
{
FrameworkElement child = default;
FrameworkElement child = default;

var count = VisualTreeHelper.GetChildrenCount(parent);
var count = VisualTreeHelper.GetChildrenCount(parent);

for (var i = 0; i < count && child == default; i++)
{
var current = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
for (var i = 0; i < count && child == default; i++)
{
var current = VisualTreeHelper.GetChild(parent, i);
var currentFe = current as FrameworkElement;
child = currentFe?.Name == name
? currentFe
: GetVisualChildByName(current, name);
}

child = current?.Name == name
? current
: GetVisualChildByName(current, name);
}
return child;
}

return child;
}
public static void GetVisualChildrenByType<T>(DependencyObject parent, ref List<T> children) where T : UIElement
{
var count = VisualTreeHelper.GetChildrenCount(parent);

public static void GetVisualChildrenByType<T>(UIElement parent, ref List<T> children) where T : UIElement
for (var i = 0; i < count; i++)
{
var count = VisualTreeHelper.GetChildrenCount(parent);
var current = VisualTreeHelper.GetChild(parent, i);

for (var i = 0; i < count; i++)
if (current is T child)
{
var current = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;

if (current is T child)
{
children.Add(child);
}
else
{
GetVisualChildrenByType(current, ref children);
}
children.Add(child);
}
else
{
GetVisualChildrenByType(current, ref children);
}
}
}

public static T GetVisualChildByType<T>(UIElement parent) where T : UIElement
{
T child = default;

var count = VisualTreeHelper.GetChildrenCount(parent);
public static T GetVisualChildByType<T>(DependencyObject parent) where T : UIElement
{
T child = default;

for (var i = 0; i < count && child == default; i++)
{
var current = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
var count = VisualTreeHelper.GetChildrenCount(parent);

child = current is T c
? c
: GetVisualChildByType<T>(current);
}
for (var i = 0; i < count && child == default; i++)
{
var current = VisualTreeHelper.GetChild(parent, i);

return child;
child = current is T c
? c
: GetVisualChildByType<T>(current);
}

return child;
}

internal static FrameworkElement GetVisualChildByNameFromOpenPopups(string name, DependencyObject element)
{
var popups = GetOpenPopups(element);

foreach (var popup in popups)
internal static FrameworkElement GetVisualChildByNameFromOpenPopups(string name, DependencyObject element)
{
var popups = GetOpenPopups(element);

foreach (var popup in popups)
{
var popupChild = popup.Child as FrameworkElement;
if (popupChild.Name == name)
{
var popupChild = popup.Child as FrameworkElement;
if (popupChild.Name == name)
{
return popupChild;
}
else
return popupChild;
}
else
{
var child = GetVisualChildByName(popupChild, name);
if (child != null)
{
var child = GetVisualChildByName(popupChild, name);
if (child != null)
{
return child;
}
return child;
}
}

return null;
}

internal static T GetVisualChildByTypeFromOpenPopups<T>(DependencyObject element)
where T : FrameworkElement
return null;
}

internal static T GetVisualChildByTypeFromOpenPopups<T>(DependencyObject element)
where T : FrameworkElement
{
var popups = GetOpenPopups(element);

foreach (var popup in popups)
{
var popups = GetOpenPopups(element);
var popupChild = (FrameworkElement)popup.Child;

foreach (var popup in popups)
var result = popupChild as T;
if (result != null)
{
var popupChild = (FrameworkElement)popup.Child;

var result = popupChild as T;
if (result != null)
{
return result;
}
result = GetVisualChildByType<T>(popupChild);
if (result != null)
{
return result;
}
return result;
}
result = GetVisualChildByType<T>(popupChild);
if (result != null)
{
return result;
}

return null;
}

internal static IEnumerable<Popup> GetOpenPopups(DependencyObject element)
{
return null;
}

internal static IEnumerable<Popup> GetOpenPopups(DependencyObject element)
{
#if WINAPPSDK
return VisualTreeHelper.GetOpenPopups(Window.Current);
return VisualTreeHelper.GetOpenPopups(Window.Current);
#else
return VisualTreeHelper.GetOpenPopupsForXamlRoot(GetXamlRoot(element));
return VisualTreeHelper.GetOpenPopupsForXamlRoot(GetXamlRoot(element));
#endif

}
}

#if !WINAPPSDK
internal static XamlRoot GetXamlRoot(DependencyObject obj)
internal static XamlRoot GetXamlRoot(DependencyObject obj)
{
XamlRoot xamlRoot = default;
if (obj is UIElement e)
{
XamlRoot xamlRoot = default;
if (obj is UIElement e)
{
xamlRoot = e.XamlRoot;
}
else if (obj is TextElement te)
{
xamlRoot = te.XamlRoot;
}
else if (obj is Microsoft.UI.Xaml.Controls.Primitives.FlyoutBase fb)
{
xamlRoot = fb.XamlRoot;
}
else
{
throw new InvalidOperationException("TreeHelper::GetXamlRoot: Can't find XamlRoot for element");
}
return xamlRoot;
xamlRoot = e.XamlRoot;
}
#endif
else if (obj is TextElement te)
{
xamlRoot = te.XamlRoot;
}
else if (obj is Microsoft.UI.Xaml.Controls.Primitives.FlyoutBase fb)
{
xamlRoot = fb.XamlRoot;
}
else
{
throw new InvalidOperationException("TreeHelper::GetXamlRoot: Can't find XamlRoot for element");
}
return xamlRoot;
}
#endif
}

0 comments on commit 06e9137

Please sign in to comment.