Skip to content

Commit

Permalink
Merge pull request #1200 from unoplatform/dev/xygu/find-ambiguous-dp
Browse files Browse the repository at this point in the history
fix: FindDependencyProperty AmbiguousMatchException
  • Loading branch information
Xiaoy312 authored Jul 19, 2024
2 parents 79396c1 + 069957c commit 422f23e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
using Windows.UI.Xaml.Controls;
#endif

using DependencyObjectExtensions = Uno.Toolkit.UI.DependencyObjectExtensions;

namespace Uno.Toolkit.RuntimeTests.Tests;

[TestClass]
[RunsOnUIThread]
internal class DependencyObjectExtensionTests
internal partial class DependencyObjectExtensionTests
{
[TestMethod]
public void When_Type_FindDependencyProperty()
Expand Down Expand Up @@ -60,4 +62,40 @@ public void When_DO_FindDependencyProperty_Attached()

Assert.AreEqual(Grid.RowProperty, dp);
}

[TestMethod]
public void When_FindDependencyProperty_Ambiguous()
{
var dp = DependencyObjectExtensions.FindDependencyPropertyInfo(typeof(Ambiguity), nameof(Ambiguity.SomeValue))
?? throw new Exception("FindDependencyPropertyInfo returned null");

Assert.AreEqual(Ambiguity.SomeValueProperty, dp.Definition);
Assert.AreEqual(typeof(int), dp.PropertyType);
}
}

internal partial class DependencyObjectExtensionTests
{
private partial class AmbiguityBase : DependencyObject
{
public object? SomeValue { get; set; }
}
private class Ambiguity : AmbiguityBase
{
#region DependencyProperty: SomeValue

public static DependencyProperty SomeValueProperty { get; } = DependencyProperty.Register(
nameof(SomeValue),
typeof(int),
typeof(Ambiguity),
new PropertyMetadata(default(int)));

public new int SomeValue
{
get => (int)GetValue(SomeValueProperty);
set => SetValue(SomeValueProperty, value);
}

#endregion
}
}
5 changes: 4 additions & 1 deletion src/Uno.Toolkit.UI/Extensions/DependencyObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ internal static void SetParent(this DependencyObject dependencyObject, object? p
{
if (dpInfo is { } && GetValue(dpInfo) is DependencyProperty dp)
{
var holderProperty = dpInfo.DeclaringType?.GetProperty(propertyName, Public | NonPublic | Instance);
// DeclaredOnly: Specifies flags that control binding and the way in which the search for members and types is conducted by reflection.
// because 'dpInfo.DeclaringType' is the guaranteed type, and we don't want an overridden property from a random base to throw AmbiguousMatchException
// ex: UIElement::Visibility & [droid]UnoViewGroup::Visibility
var holderProperty = dpInfo.DeclaringType?.GetProperty(propertyName, Public | NonPublic | Instance | DeclaredOnly);
var propertyType =
holderProperty?.PropertyType ??
dpInfo.DeclaringType?.GetMethod($"Get{propertyName}", Public | NonPublic | Static)?.ReturnType ??
Expand Down

0 comments on commit 422f23e

Please sign in to comment.