Browse Source

Fix #20625: remove automatic DataContext fallback to root type

Address review feedback by removing the automatic fallback inference
to the root type in AvaloniaXamlIlDataContextTypeTransformer, as it
is not necessary to fix the issue and is not desired behavior.

Also removes the unit tests that validated this specific fallback.
pull/21248/head
João Cruz 5 months ago
parent
commit
57c838820c
  1. 11
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs
  2. 34
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

11
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs

@ -118,17 +118,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
// Notify the user that we were unable to infer the data context type if they use a compiled binding. // Notify the user that we were unable to infer the data context type if they use a compiled binding.
inferredDataContextTypeNode = new AvaloniaXamlIlUninferrableDataContextMetadataNode(on); inferredDataContextTypeNode = new AvaloniaXamlIlUninferrableDataContextMetadataNode(on);
} }
if (inferredDataContextTypeNode is null
&& directiveDataContextTypeNode is null
&& !context.ParentNodes().OfType<XamlAstConstructableObjectNode>().Any())
{
// Root nodes without an explicit x:DataType still need a deterministic
// starting type for compiled bindings. Falling back to the root CLR type
// allows expressions to compile and avoids stale inference from unrelated
// branches, while runtime DataContext semantics remain unchanged.
inferredDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on, on.Type.GetClrType());
}
} }
return directiveDataContextTypeNode ?? inferredDataContextTypeNode ?? node; return directiveDataContextTypeNode ?? inferredDataContextTypeNode ?? node;

34
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs

@ -427,23 +427,6 @@ namespace Avalonia.Markup.Xaml.UnitTests
} }
} }
[Fact]
public void Compiled_Binding_Should_Fallback_To_Root_Type_Without_Explicit_DataType()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var parsed = (CompiledBindingRootMock)AvaloniaRuntimeXamlLoader.Parse(@"
<UserControl x:Class='Avalonia.Markup.Xaml.UnitTests.CompiledBindingRootMock'
xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<TextBlock Text='{CompiledBinding Greeting}'/>
</UserControl>");
parsed.DataContext = parsed;
var textBlock = (TextBlock)parsed.Content!;
Assert.Equal("Hello", textBlock.Text);
}
}
[Fact] [Fact]
public void Compiled_Binding_Should_Resolve_Named_Root_DataContext_In_ItemTemplate() public void Compiled_Binding_Should_Resolve_Named_Root_DataContext_In_ItemTemplate()
{ {
@ -465,23 +448,6 @@ namespace Avalonia.Markup.Xaml.UnitTests
} }
} }
[Fact]
public void Compiled_Binding_Root_Fallback_Should_Not_Crash_With_Incompatible_Runtime_DataContext()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var parsed = (CompiledBindingRootMock)AvaloniaRuntimeXamlLoader.Parse(@"
<UserControl x:Class='Avalonia.Markup.Xaml.UnitTests.CompiledBindingRootMock'
xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<TextBlock Text='{CompiledBinding Greeting}'/>
</UserControl>");
parsed.DataContext = new object();
var textBlock = (TextBlock)parsed.Content!;
Assert.Null(textBlock.Text);
}
}
[Fact] [Fact]
public void Compiled_Binding_Should_Resolve_Root_Command_From_Nested_ItemTemplate_Namescope() public void Compiled_Binding_Should_Resolve_Root_Command_From_Nested_ItemTemplate_Namescope()
{ {

Loading…
Cancel
Save