Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions build/PackageDiffIgnore.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2940,6 +2940,9 @@
<Member fullName="System.Boolean Uno.UI.FeatureConfiguration/Cursors::UseHandForInteraction()" reason="Removed Cursors.UseHandForInteraction flag (#2052, breaking changes for 7.0)" />
<Member fullName="System.Boolean Uno.UI.FeatureConfiguration/WebView2::IsInspectable()" reason="Removed WebView2.IsInspectable flag, superseded by EnableDevTools (#2052, breaking changes for 7.0)" />
<Member fullName="System.Boolean Uno.UI.FeatureConfiguration/AndroidSettings::IsEdgeToEdgeEnabled()" reason="Removed AndroidSettings.IsEdgeToEdgeEnabled flag; edge-to-edge is now unconditional on Skia-Android (#2052, breaking changes for 7.0)" />
<!-- Property types aligned to the WinUI metadata (#2086, breaking changes for 7.0). -->
<Member fullName="System.Object Microsoft.UI.Xaml.Data.Binding::ElementName()" reason="WinUI sync: Binding.ElementName narrowed from object to string to match WinUI metadata (#2086, breaking changes for 7.0)" />
<Member fullName="Microsoft.UI.Xaml.Media.Animation.IEasingFunction Microsoft.UI.Xaml.Media.Animation.DoubleAnimation::EasingFunction()" reason="WinUI sync: DoubleAnimation.EasingFunction changed from IEasingFunction to EasingFunctionBase to match WinUI metadata (#2086, breaking changes for 7.0)" />
</Properties>
<Methods>
<!-- StackLayout.DisableVirtualizationProperty DP getter: paired with the removed property (see <Properties> above). DisableVirtualization is a plain CLR property in WinUI. -->
Expand All @@ -2957,6 +2960,11 @@
<Member fullName="System.Void Microsoft.UI.Xaml.Controls.NavigationViewItem.set_MenuItems(System.Collections.Generic.IList`1&lt;System.Object&gt; value)" reason="Aligned to WinUI IDL (get-only / non-activatable)" />
<Member fullName="System.Void Microsoft.UI.Xaml.Controls.NavigationViewTemplateSettings.set_OpenPaneLength(System.Double value)" reason="Aligned to WinUI IDL (get-only / non-activatable)" />
<Member fullName="System.Void Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs..ctor()" reason="Aligned to WinUI IDL (get-only / non-activatable)" />
<!-- Binding.ElementName (object->string) and DoubleAnimation.EasingFunction (IEasingFunction->EasingFunctionBase) accessors, aligned to WinUI metadata (#2086, breaking changes for 7.0). -->
<Member fullName="System.Object Microsoft.UI.Xaml.Data.Binding.get_ElementName()" reason="WinUI sync: Binding.ElementName narrowed from object to string (#2086, breaking changes for 7.0)" />
<Member fullName="System.Void Microsoft.UI.Xaml.Data.Binding.set_ElementName(System.Object value)" reason="WinUI sync: Binding.ElementName narrowed from object to string (#2086, breaking changes for 7.0)" />
<Member fullName="Microsoft.UI.Xaml.Media.Animation.IEasingFunction Microsoft.UI.Xaml.Media.Animation.DoubleAnimation.get_EasingFunction()" reason="WinUI sync: DoubleAnimation.EasingFunction changed from IEasingFunction to EasingFunctionBase (#2086, breaking changes for 7.0)" />
<Member fullName="System.Void Microsoft.UI.Xaml.Media.Animation.DoubleAnimation.set_EasingFunction(Microsoft.UI.Xaml.Media.Animation.IEasingFunction value)" reason="WinUI sync: DoubleAnimation.EasingFunction changed from IEasingFunction to EasingFunctionBase (#2086, breaking changes for 7.0)" />
</Methods>
</IgnoreSet>
<![CDATA[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public _View Build(object __ResourceOwner_1, global::Microsoft.UI.Xaml.TemplateM
new Microsoft.UI.Xaml.Data.Binding()
{
Path = @"Tag",
ElementName = _topLevelSubject,
ElementNameSubject = _topLevelSubject,
}
);
global::Uno.UI.FrameworkElementHelper.SetBaseUri(__p1, __baseUri_Binding_ElementName_In_Template_66bf0a54f1801c397a6fa4930a237eca);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private void InitializeComponent()
new Microsoft.UI.Xaml.Data.Binding()
{
Path = @"Tag",
ElementName = _topLevelSubject,
ElementNameSubject = _topLevelSubject,
Converter = (global::Microsoft.UI.Xaml.Data.IValueConverter)global::Uno.UI.ResourceResolverSingleton.Instance.ResolveResourceStatic("Binding_Xaml_Object_With_Common_Properties_Return_Value_Converter", typeof(global::Microsoft.UI.Xaml.Data.IValueConverter), context: global::MyProject.GlobalStaticResources.__ParseContext_),
ConverterParameter = @"topLevel",
ConverterLanguage = "topLevel",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private void InitializeComponent()
new Microsoft.UI.Xaml.Data.Binding()
{
Path = @"Tag",
ElementName = _topLevelSubject,
ElementNameSubject = _topLevelSubject,
Converter = new global::Uno.UI.Tests.Windows_UI_Xaml_Data.BindingTests.Controls.Binding_Xaml_Object_With_Xaml_Object_Properties_Return_Value_Converter(),
ConverterParameter = "topLevel",
ConverterLanguage = "topLevel",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ public _View Build(object __ResourceOwner_1, global::Microsoft.UI.Xaml.TemplateM
new Microsoft.UI.Xaml.Data.Binding()
{
Path = @"EditDurationCommand",
ElementName = _ActivitiesListSubject,
ElementNameSubject = _ActivitiesListSubject,
}
);
global::Uno.UI.FrameworkElementHelper.SetBaseUri(__p1, __baseUri_MainPage_d6cd66944958ced0c513e0a04797b51d);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4815,8 +4815,17 @@ private string BuildMemberPropertyValue(XamlMemberDefinition m, bool isTemplateB
}
else
{
var memberName = m.Member.Name == "_PositionalParameters" ? "Path" : m.Member.Name;

// The public ElementName is a string (WinUI parity); the routing subject used
// for late binding is carried by the Uno-only ElementNameSubject property.
if (memberName == "ElementName")
{
memberName = "ElementNameSubject";
}

return "{0} = {1}".InvariantCultureFormat(
m.Member.Name == "_PositionalParameters" ? "Path" : m.Member.Name,
memberName,
BuildBindingOption(m, FindPropertyType(m.Member), isTemplateBindingAttachedProperty));
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Uno.UI/DataBinding/BindingExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Binding binding
.ToArray();
}

if (ParentBinding.ElementName != null)
if (ParentBinding.ElementNameSubject != null)
{
_isElementNameSource = true;
}
Expand Down Expand Up @@ -364,7 +364,7 @@ private UpdateSourceTrigger ResolveUpdateSourceTrigger()

internal void ApplyElementName()
{
if (ParentBinding.ElementName is ElementNameSubject elementNameSubject)
if (ParentBinding.ElementNameSubject is { } elementNameSubject)
{

if (elementNameSubject.IsLoadTimeBound)
Expand Down
6 changes: 4 additions & 2 deletions src/Uno.UI/UI/Xaml/Controls/SwipeControl/SwipeControl.Uno.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ private async Task AnimateTransforms(bool useInertiaSpeed, double inertiaSpeed)
{
To = desiredPosition,
Duration = new Duration(TimeSpan.FromSeconds(duration)),
EasingFunction = useInertiaSpeed ? (IEasingFunction)LinearEase.Instance : new QuadraticEase()
// A null EasingFunction is interpolated linearly (the animator substitutes LinearEase).
EasingFunction = useInertiaSpeed ? null : new QuadraticEase()
{
EasingMode = EasingMode.EaseInOut
}
Expand All @@ -503,7 +504,8 @@ private async Task AnimateTransforms(bool useInertiaSpeed, double inertiaSpeed)
{
To = stackDesiredPosition,
Duration = new Duration(TimeSpan.FromSeconds(duration)),
EasingFunction = useInertiaSpeed ? (IEasingFunction)LinearEase.Instance : new QuadraticEase()
// A null EasingFunction is interpolated linearly (the animator substitutes LinearEase).
EasingFunction = useInertiaSpeed ? null : new QuadraticEase()
{
EasingMode = EasingMode.EaseInOut
}
Expand Down
15 changes: 13 additions & 2 deletions src/Uno.UI/UI/Xaml/Data/Binding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,19 @@ public static implicit operator Binding(string path)
/// <summary>
/// Gets or sets the name of the element to use as the binding source for the Binding.
/// </summary>
/// <value>The name of the element, or an ElementNameSubject instance that can be used to monitor the element name instance changes.</value>
public object ElementName { get; set; }
/// <value>The name of the element.</value>
public string ElementName { get; set; }

Comment on lines 96 to +100
/// <summary>
/// Routes the availability of the element instance for a late-bound ElementName binding.
/// </summary>
/// <remarks>
/// Uno-only seam set by the XAML code generator and runtime reader. It must be public
/// because the compiled-XAML output lives in the consuming assembly, which has no access
/// to Uno.UI internals (same rationale as <see cref="CompiledSource"/>).
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public ElementNameSubject ElementNameSubject { get; set; }

/// <summary>
/// Gets or sets the value to use when the binding is unable to return a value.
Expand Down
1 change: 1 addition & 0 deletions src/Uno.UI/UI/Xaml/DependencyPropertyDetailsCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ internal void CloneToForHotReload(DependencyPropertyDetailsCollection other, Dep
newBinding.Mode = binding.Mode;
newBinding.TargetNullValue = binding.TargetNullValue;
newBinding.ElementName = binding.ElementName;
newBinding.ElementNameSubject = binding.ElementNameSubject;
newBinding.FallbackValue = binding.FallbackValue;
Comment on lines 76 to 79
if (binding.RelativeSource is { } relativeSource)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ private Binding BuildBindingExpression(object? instance, object? rootInstance, X

case nameof(Binding.ElementName):
var subject = new ElementNameSubject();
binding.ElementName = subject;
binding.ElementNameSubject = subject;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Binding.ElementName string property is not set anywhere in this handler, so binding.ElementName will be null after the runtime reader parses {Binding ElementName=Foo}. The subject carries the resolution machinery and the binding works correctly, but reading back binding.ElementName returns null instead of "Foo".

WinUI's contract is that a property you write in XAML is readable back from the binding object. To keep that roundtrip consistent, consider also setting the string after the if check:

if (bindingProperty.Value?.ToString() is { } value)
{
    binding.ElementName = value;   // keep public string in sync
    AddElementName(value, subject);
}

This doesn't affect binding resolution (which goes through the subject), but avoids a surprising null for tooling or diagnostic code that inspects binding.ElementName.


if (bindingProperty.Value?.ToString() is { } value)
{
Expand Down
6 changes: 3 additions & 3 deletions src/Uno.UI/UI/Xaml/Media/Animation/DoubleAnimation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ public bool EnableDependentAnimation
public static DependencyProperty EnableDependentAnimationProperty { get; } =
DependencyProperty.Register("EnableDependentAnimation", typeof(bool), typeof(DoubleAnimation), new FrameworkPropertyMetadata(false));

public IEasingFunction EasingFunction
public EasingFunctionBase EasingFunction
{
get => (IEasingFunction)GetValue(EasingFunctionProperty);
get => (EasingFunctionBase)GetValue(EasingFunctionProperty);
set => SetValue(EasingFunctionProperty, value);
}

Expand All @@ -73,7 +73,7 @@ public IEasingFunction EasingFunction
float? IAnimation<float>.By => (float?)By;

public static DependencyProperty EasingFunctionProperty { get; } =
DependencyProperty.Register("EasingFunction", typeof(IEasingFunction), typeof(DoubleAnimation), new FrameworkPropertyMetadata(null));
DependencyProperty.Register("EasingFunction", typeof(EasingFunctionBase), typeof(DoubleAnimation), new FrameworkPropertyMetadata(null));

void ITimeline.Begin() => _animationImplementation.Begin();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,7 @@ private static bool ArePropertiesMatching(IPropertySymbol uapProperty, IProperty

// Property type of ContentTemplateRoot is diverging from UWP.
// In Uno we use the native view for each platform Android.Views.View, UIKit.UIView, AppKit.NSView
if (!AreMatching(uapProperty.Type, unoProperty.Type) && uapProperty.Name != "ContentTemplateRoot" &&
// object vs UIElement
uapProperty.Name != "Content" &&
// IEasingFunction vs EasingFunctionBase
uapProperty.Name != "EasingFunction" &&
// string vs object
uapProperty.Name != "ElementName")
if (!AreMatching(uapProperty.Type, unoProperty.Type) && uapProperty.Name != "ContentTemplateRoot")
{
return false;
}
Expand Down
Loading