Skip to content

Commit

Permalink
fix(xBind): Fix xBind to other control without code-behind base class
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromelaban committed Oct 1, 2021
1 parent eb59473 commit 76b2dba
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<UserControl
x:Class="Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls.xBind_UserControl_To_OtherControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<local:xBind_UserControl_To_OtherControl_Inner
MyProperty="{x:Bind MyProperty, Mode=OneWay}" />
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls
{
#pragma warning disable UXAML0002
public sealed partial class xBind_UserControl_To_OtherControl /* : UserControl: Don't specify the base type so x:Bind generator lookups uses the XAML control type */
#pragma warning restore UXAML0002
{
public xBind_UserControl_To_OtherControl()
{
this.InitializeComponent();
}

public string MyProperty
{
get { return (string)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}

// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(string), typeof(xBind_UserControl_To_OtherControl), new PropertyMetadata("Default string"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<UserControl
x:Class="Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls.xBind_UserControl_To_OtherControl_Inner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<Grid>
<TextBlock x:Name="tb1" x:FieldModifier="public" Text="{x:Bind MyProperty, Mode=OneWay}" />
</Grid>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace Uno.UI.Tests.Windows_UI_Xaml_Data.xBindTests.Controls
{
#pragma warning disable UXAML0002
public sealed partial class xBind_UserControl_To_OtherControl_Inner /* : UserControl: Don't specify the base type so x:Bind generator lookups uses the XAML control type */
#pragma warning restore UXAML0002
{
public xBind_UserControl_To_OtherControl_Inner()
{
this.InitializeComponent();
}

public string MyProperty
{
get { return (string)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}

// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(string), typeof(xBind_UserControl_To_OtherControl_Inner), new PropertyMetadata("Default string"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,25 @@ public void When_Initial_Value()

Assert.AreEqual("Default string", _MyProperty.Text);
}

[TestMethod]
public void When_xBind_UserControl_To_OtherControl()
{
var SUT = new xBind_UserControl_To_OtherControl();

var tb1 = SUT.FindName("tb1") as TextBlock;
Assert.IsNotNull(tb1);
Assert.AreEqual("", tb1.Text);

SUT.ForceLoaded();

Assert.AreEqual("Default string", tb1.Text);

var inner = SUT.Content as xBind_UserControl_To_OtherControl_Inner;

Assert.IsNotNull(inner);
Assert.AreEqual("Default string", inner.MyProperty);
Assert.AreEqual("Default string", tb1.Text);
}
}
}
9 changes: 9 additions & 0 deletions src/Uno.UI/UI/Xaml/Data/BindingHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
Expand All @@ -9,18 +10,26 @@ namespace Uno.UI.Xaml
{
public static class BindingHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Binding SetBindingXBindProvider(Binding binding, object compiledSource, Func<object, object> xBindSelector, string[]? propertyPaths = null)
=> SetBindingXBindProvider(binding, compiledSource, xBindSelector, null, propertyPaths);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Binding SetBindingXBindProvider(Binding binding, object compiledSource, Func<object, object> xBindSelector, Action<object, object>? xBindBack, string[]? propertyPaths = null)
{
binding.SetBindingXBindProvider(compiledSource, xBindSelector, xBindBack, propertyPaths);
return binding;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AttachedDependencyObject GetDependencyObjectForXBind(this object instance)
=> DependencyObjectExtensions.GetAttachedDependencyObject(instance);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static DependencyObject GetDependencyObjectForXBind(this DependencyObject instance)
=> instance;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ApplyXBind(this DependencyObject instance)
=> (instance as IDependencyObjectStoreProvider)?.Store.ApplyCompiledBindings();

Expand Down

0 comments on commit 76b2dba

Please sign in to comment.