Skip to content

Commit

Permalink
Revert "[X] do not apply Bindings if DataType doesnt match (#22056)" (#…
Browse files Browse the repository at this point in the history
…24693)

This reverts commit cb0a332.
  • Loading branch information
PureWeen authored Sep 12, 2024
1 parent fd718a1 commit f91ee55
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 93 deletions.
13 changes: 2 additions & 11 deletions src/Controls/src/Core/Binding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using Microsoft.Maui.Controls.Xaml.Diagnostics;

namespace Microsoft.Maui.Controls
{
Expand Down Expand Up @@ -106,8 +105,6 @@ public string UpdateSourceEventName
}
}

internal Type DataType { get; set; }

internal override void Apply(bool fromTarget)
{
base.Apply(fromTarget);
Expand All @@ -123,14 +120,7 @@ internal override void Apply(object context, BindableObject bindObj, BindablePro
object src = _source;
var isApplied = IsApplied;

var bindingContext = src ?? Context ?? context;
if (DataType != null && bindingContext != null && !DataType.IsAssignableFrom(bindingContext.GetType()))
{
BindingDiagnostics.SendBindingFailure(this, "Binding", "Mismatch between the specified x:DataType and the current binding context");
bindingContext = null;
}

base.Apply(bindingContext, bindObj, targetProperty, fromBindingContextChanged, specificity);
base.Apply(src ?? context, bindObj, targetProperty, fromBindingContextChanged, specificity);

if (src != null && isApplied && fromBindingContextChanged)
return;
Expand All @@ -141,6 +131,7 @@ internal override void Apply(object context, BindableObject bindObj, BindablePro
}
else
{
object bindingContext = src ?? Context ?? context;
if (_expression == null)
_expression = new BindingExpression(this, SelfPath);
_expression.Apply(bindingContext, bindObj, targetProperty, specificity);
Expand Down
5 changes: 0 additions & 5 deletions src/Controls/src/Core/IXamlDataTypeProvider.cs

This file was deleted.

13 changes: 2 additions & 11 deletions src/Controls/src/Xaml/MarkupExtensions/BindingExtension.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.ComponentModel;
using System.Linq.Expressions;
using Microsoft.Maui.Controls.Internals;

namespace Microsoft.Maui.Controls.Xaml
{
[ContentProperty(nameof(Path))]
[AcceptEmptyServiceProvider]
public sealed class BindingExtension : IMarkupExtension<BindingBase>
{
public string Path { get; set; } = Binding.SelfPath;
Expand All @@ -21,22 +21,13 @@ public sealed class BindingExtension : IMarkupExtension<BindingBase>

BindingBase IMarkupExtension<BindingBase>.ProvideValue(IServiceProvider serviceProvider)
{
if (TypedBinding is null) {
Type bindingXDataType = null;
if ((serviceProvider.GetService(typeof(IXamlTypeResolver)) is IXamlTypeResolver typeResolver)
&& (serviceProvider.GetService(typeof(IXamlDataTypeProvider)) is IXamlDataTypeProvider dataTypeProvider)
&& dataTypeProvider.BindingDataType != null)
{
typeResolver.TryResolve(dataTypeProvider.BindingDataType, out bindingXDataType);
}
if (TypedBinding == null)
return new Binding(Path, Mode, Converter, ConverterParameter, StringFormat, Source)
{
UpdateSourceEventName = UpdateSourceEventName,
FallbackValue = FallbackValue,
TargetNullValue = TargetNullValue,
DataType = bindingXDataType,
};
}

TypedBinding.Mode = Mode;
TypedBinding.Converter = Converter;
Expand Down
56 changes: 0 additions & 56 deletions src/Controls/src/Xaml/XamlServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ internal XamlServiceProvider(INode node, HydrationContext context)
IXmlLineInfoProvider = new XmlLineInfoProvider(xmlLineInfo);

IValueConverterProvider = new ValueConverterProvider();

if (node is IElementNode elementNode)
Add(typeof(IXamlDataTypeProvider), new XamlDataTypeProvider(elementNode));
}

public XamlServiceProvider() => IValueConverterProvider = new ValueConverterProvider();
Expand Down Expand Up @@ -265,57 +262,4 @@ public string LookupNamespace(string prefix)
public string LookupPrefix(string namespaceName) => throw new NotImplementedException();
public void Add(string prefix, string ns) => namespaces.Add(prefix, ns);
}

class XamlDataTypeProvider : IXamlDataTypeProvider
{
public XamlDataTypeProvider(IElementNode node)
{
static IElementNode GetParent(IElementNode node)
{
return node switch
{
{ Parent: ListNode { Parent: IElementNode parentNode } } => parentNode,
{ Parent: IElementNode parentNode } => parentNode,
_ => null,
};
}

static bool IsBindingContextBinding(IElementNode node)
{
if ( ApplyPropertiesVisitor.TryGetPropertyName(node, node.Parent, out XmlName name)
&& name.NamespaceURI == ""
&& name.LocalName == nameof(BindableObject.BindingContext))
return true;
return false;
}

INode dataTypeNode = null;
IElementNode n = node as IElementNode;

// Special handling for BindingContext={Binding ...}
// The order of checks is:
// - x:DataType on the binding itself
// - SKIP looking for x:DataType on the parent
// - continue looking for x:DataType on the parent's parent...
IElementNode skipNode = null;
if (IsBindingContextBinding(node))
{
skipNode = GetParent(node);
}

while (n != null)
{
if (n != skipNode && n.Properties.TryGetValue(XmlName.xDataType, out dataTypeNode))
{
break;
}

n = GetParent(n);
}
if (dataTypeNode is ValueNode valueNode)
BindingDataType = valueNode.Value as string;

}
public string BindingDataType { get; }
}
}
14 changes: 4 additions & 10 deletions src/Controls/tests/Xaml.UnitTests/BindingsCompiler.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ public class Tests
{
[SetUp] public void Setup() => DispatcherProvider.SetCurrent(new DispatcherProviderStub());
[TearDown] public void TearDown() => DispatcherProvider.SetCurrent(null);

[Test]
public void TestCompiledBindings([Values(false, true)]bool useCompiledXaml)

[TestCase(false)]
[TestCase(true)]
public void Test(bool useCompiledXaml)
{
if (useCompiledXaml)
MockCompiler.Compile(typeof(BindingsCompiler));
Expand Down Expand Up @@ -116,13 +117,6 @@ public void TestCompiledBindings([Values(false, true)]bool useCompiledXaml)
layout.BindingContext = new object();
Assert.AreEqual(null, layout.label0.Text);
}

[Test]
public void BindingsNotAppliedWithWrongContext([Values(false, true)]bool useCompiledXaml)
{
var page = new BindingsCompiler(useCompiledXaml) { BindingContext = new {Text="Foo"} };
Assert.AreEqual(null, page.label0.Text);
}
}
}

Expand Down

0 comments on commit f91ee55

Please sign in to comment.