зеркало из https://github.com/AvaloniaUI/Avalonia.git
XamlX update: IProvideValueTarget fixes and nested-types support (#17021)
* Update XamlX * Include nested types PR as well * Fix Designer.HostApp compilation on older targets
This commit is contained in:
Родитель
2e83ac1a04
Коммит
e22cfa8424
|
@ -12,9 +12,6 @@
|
|||
<Setter Property="FontSize" Value="18"/>
|
||||
</Style>
|
||||
</Window.Styles>
|
||||
<Window.Resources>
|
||||
<vm:TestItem x:Key="SharedItem" StringValue="shared" />
|
||||
</Window.Resources>
|
||||
|
||||
<TabControl>
|
||||
<TabItem Header="Basic">
|
||||
|
@ -54,9 +51,9 @@
|
|||
<TextBox Watermark="Value of first TextBox" UseFloatingWatermark="True"
|
||||
Text="{Binding #first.Text, Mode=TwoWay}"/>
|
||||
<TextBox Watermark="Value of SharedItem.StringValue" UseFloatingWatermark="True"
|
||||
Text="{Binding StringValue, Source={StaticResource SharedItem}, Mode=TwoWay}"/>
|
||||
Text="{Binding StringValue, Source={StaticResource SharedItem}, Mode=TwoWay, DataType=vm:MainWindowViewModel+TestItem}"/>
|
||||
<TextBox Watermark="Value of SharedItem.StringValue (duplicate)" UseFloatingWatermark="True"
|
||||
Text="{Binding StringValue, Source={StaticResource SharedItem}, Mode=TwoWay}"/>
|
||||
Text="{Binding StringValue, Source={StaticResource SharedItem}, Mode=TwoWay, DataType=vm:MainWindowViewModel+TestItem}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="18" Spacing="4" Width="200" HorizontalAlignment="Left">
|
||||
<TextBlock FontSize="16" Text="Scheduler"/>
|
||||
|
@ -70,7 +67,7 @@
|
|||
<TabItem Header="ListBox">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel.DataTemplates>
|
||||
<DataTemplate DataType="vm:TestItem">
|
||||
<DataTemplate DataType="vm:MainWindowViewModel+TestItem">
|
||||
<TextBlock Text="{Binding StringValue}"/>
|
||||
</DataTemplate>
|
||||
</StackPanel.DataTemplates>
|
||||
|
@ -84,7 +81,7 @@
|
|||
</StackPanel>
|
||||
<ContentControl Content="{ReflectionBinding Selection.SelectedItems[0]}">
|
||||
<ContentControl.DataTemplates>
|
||||
<DataTemplate DataType="vm:TestItem">
|
||||
<DataTemplate DataType="vm:MainWindowViewModel+TestItem">
|
||||
<local:TestItemView></local:TestItemView>
|
||||
</DataTemplate>
|
||||
</ContentControl.DataTemplates>
|
||||
|
@ -126,7 +123,7 @@
|
|||
</TabItem.Resources>
|
||||
<StackPanel>
|
||||
<!-- Tests for #10856 -->
|
||||
<TextBlock Text="{local:GenericMarkupExtension, Value=Red, x:TypeArguments=Color}"/>
|
||||
<TextBlock Text="{local:GenericMarkupExtension Value=Red, x:TypeArguments=Color}"/>
|
||||
<TextBlock HorizontalAlignment="Left"
|
||||
Text="{Binding $self.Background, Converter={StaticResource BrushConverter}}">
|
||||
<TextBlock.Background>
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace BindingDemo
|
|||
{
|
||||
public MainWindow()
|
||||
{
|
||||
Resources["SharedItem"] = new MainWindowViewModel.TestItem() { StringValue = "shared" };
|
||||
this.InitializeComponent();
|
||||
this.DataContext = new MainWindowViewModel();
|
||||
this.AttachDevTools();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
|
||||
xmlns:viewModels="using:BindingDemo.ViewModels"
|
||||
x:Class="BindingDemo.TestItemView"
|
||||
x:DataType="viewModels:TestItem">
|
||||
x:DataType="viewModels:MainWindowViewModel+TestItem">
|
||||
<StackPanel>
|
||||
<TextBlock Classes="h1" Text="{Binding StringValue}"/>
|
||||
<TextBox Text="{Binding Detail}" AcceptsReturn="True"/>
|
||||
|
|
|
@ -115,5 +115,24 @@ namespace BindingDemo.ViewModels
|
|||
{
|
||||
return BooleanFlag;
|
||||
}
|
||||
|
||||
// Nested class, jsut so we can test it in XAML
|
||||
public class TestItem : ViewModelBase
|
||||
{
|
||||
private string _stringValue = "String Value";
|
||||
private string _detail;
|
||||
|
||||
public string StringValue
|
||||
{
|
||||
get { return _stringValue; }
|
||||
set { this.RaiseAndSetIfChanged(ref this._stringValue, value); }
|
||||
}
|
||||
|
||||
public string Detail
|
||||
{
|
||||
get { return _detail; }
|
||||
set { this.RaiseAndSetIfChanged(ref this._detail, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,21 +2,5 @@ using MiniMvvm;
|
|||
|
||||
namespace BindingDemo.ViewModels
|
||||
{
|
||||
public class TestItem : ViewModelBase
|
||||
{
|
||||
private string _stringValue = "String Value";
|
||||
private string _detail;
|
||||
|
||||
public string StringValue
|
||||
{
|
||||
get { return _stringValue; }
|
||||
set { this.RaiseAndSetIfChanged(ref this._stringValue, value); }
|
||||
}
|
||||
|
||||
public string Detail
|
||||
{
|
||||
get { return _detail; }
|
||||
set { this.RaiseAndSetIfChanged(ref this._detail, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -334,13 +334,17 @@ internal class AvaloniaXamlIlOptionMarkupExtensionTransformer : IXamlAstTransfor
|
|||
public bool IsPrivate => false;
|
||||
public bool IsFamily => false;
|
||||
public bool IsStatic => false;
|
||||
public bool ContainsGenericParameters => false;
|
||||
public bool IsGenericMethod => false;
|
||||
public bool IsGenericMethodDefinition => false;
|
||||
public IXamlType ReturnType => ExtensionNodeContainer.GetReturnType();
|
||||
public IReadOnlyList<IXamlType> Parameters { get; }
|
||||
public IXamlType DeclaringType { get; }
|
||||
public IXamlMethod MakeGenericMethod(IReadOnlyList<IXamlType> typeArguments) => throw new NotImplementedException();
|
||||
public IReadOnlyList<IXamlCustomAttribute> CustomAttributes => Array.Empty<IXamlCustomAttribute>();
|
||||
|
||||
public IReadOnlyList<IXamlCustomAttribute> CustomAttributes => [];
|
||||
public IXamlParameterInfo GetParameterInfo(int index) => new AnonymousParameterInfo(Parameters[index], index);
|
||||
public IReadOnlyList<IXamlType> GenericParameters => [];
|
||||
public IReadOnlyList<IXamlType> GenericArguments => [];
|
||||
|
||||
public void EmitCall(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
||||
{
|
||||
|
|
|
@ -168,6 +168,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|||
public bool IsPrivate => false;
|
||||
public bool IsFamily => false;
|
||||
public bool IsStatic => true;
|
||||
public bool ContainsGenericParameters => false;
|
||||
public bool IsGenericMethod => false;
|
||||
public bool IsGenericMethodDefinition => false;
|
||||
public string Name { get; protected set; }
|
||||
public IXamlType DeclaringType { get; }
|
||||
public IXamlMethod MakeGenericMethod(IReadOnlyList<IXamlType> typeArguments)
|
||||
|
@ -181,6 +184,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|||
|
||||
public IReadOnlyList<IXamlCustomAttribute> CustomAttributes => DeclaringType.CustomAttributes;
|
||||
public IXamlParameterInfo GetParameterInfo(int index) => new AnonymousParameterInfo(Parameters[index], index);
|
||||
public IReadOnlyList<IXamlType> GenericParameters => [];
|
||||
public IReadOnlyList<IXamlType> GenericArguments => [];
|
||||
|
||||
public void EmitCall(IXamlILEmitter emitter)
|
||||
{
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 14fed0cb0666a9b3f71cb635cf61eb6010d4ff64
|
||||
Subproject commit ab84721302d6ed2b8b65315f3c54217693640348
|
|
@ -16,6 +16,7 @@
|
|||
<Compile Include="..\..\..\src\Markup\Avalonia.Markup.Xaml.Loader\CompilerDynamicDependencies.cs" />
|
||||
<Compile Include="..\..\..\src\Avalonia.Base\Compatibility\NullableAttributes.cs" Link="Compatibility\NullableAttributes.cs" />
|
||||
<Compile Include="..\..\..\src\Avalonia.Base\Compatibility\TrimmingAttributes.cs" Link="Compatibility\TrimmingAttributes.cs" />
|
||||
<Compile Include="..\..\Shared\StringCompatibilityExtensions.cs" Link="Compatibility\StringCompatibilityExtensions.cs" />
|
||||
<Compile Include="..\..\..\src\Shared\IsExternalInit.cs" Link="Compatibility\IsExternalInit.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\..\src\Markup\Avalonia.Markup.Xaml.Loader\IncludeXamlIlSre.props" />
|
||||
|
|
|
@ -297,6 +297,15 @@ internal class RoslynMethod : IXamlMethod
|
|||
public bool IsFamily => _symbol.DeclaredAccessibility == Accessibility.Protected;
|
||||
|
||||
public bool IsStatic => false;
|
||||
public bool ContainsGenericParameters => _symbol.TypeParameters.Any();
|
||||
public bool IsGenericMethod => _symbol.IsGenericMethod;
|
||||
public bool IsGenericMethodDefinition => _symbol.IsDefinition && _symbol.IsGenericMethod;
|
||||
|
||||
public IReadOnlyList<IXamlType> GenericParameters => throw new NotImplementedException();
|
||||
|
||||
public IReadOnlyList<IXamlType> GenericArguments => _symbol.TypeArguments
|
||||
.Select(ga => new RoslynType((INamedTypeSymbol)ga, _assembly))
|
||||
.ToArray();
|
||||
|
||||
public IXamlType ReturnType => new RoslynType((INamedTypeSymbol) _symbol.ReturnType, _assembly);
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Documents;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Data.Core;
|
||||
using Avalonia.Markup.Xaml.MarkupExtensions;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.UnitTests;
|
||||
using Xunit;
|
||||
|
||||
namespace Avalonia.Markup.Xaml.UnitTests.Xaml;
|
||||
|
||||
public class ProvideValueTargetTests : XamlTestBase
|
||||
{
|
||||
[Fact]
|
||||
public void ProvideValueTarget_Has_Correct_Targets_Set()
|
||||
{
|
||||
using var _ = UnitTestApplication.Start(TestServices.StyledWindow);
|
||||
|
||||
var capturedTargets = new CapturedTargets();
|
||||
AvaloniaLocator.CurrentMutable.BindToSelf(capturedTargets);
|
||||
|
||||
AvaloniaRuntimeXamlLoader.Load(@"
|
||||
<Window xmlns='https://github.com/avaloniaui'
|
||||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
|
||||
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.Xaml;assembly=Avalonia.Markup.Xaml.UnitTests'
|
||||
Foreground='{local:CapturingTargetsMarkup}'
|
||||
x:CompileBindings='True'>
|
||||
|
||||
<TextBlock Tag='{Binding Source={local:CapturingTargetsMarkup}}'
|
||||
Background='{local:CapturingTargetsMarkup}' />
|
||||
|
||||
</Window>");
|
||||
|
||||
Assert.Collection(capturedTargets.Targets,
|
||||
item =>
|
||||
{
|
||||
Assert.IsType<Window>(item.TargetObject);
|
||||
Assert.Equal(TextElement.ForegroundProperty, item.TargetProperty);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.IsAssignableFrom<CompiledBindingExtension>(item.TargetObject);
|
||||
var prop = Assert.IsType<ClrPropertyInfo>(item.TargetProperty);
|
||||
Assert.Equal(nameof(Binding.Source), prop.Name);
|
||||
},
|
||||
item =>
|
||||
{
|
||||
Assert.IsType<TextBlock>(item.TargetObject);
|
||||
Assert.Equal(TextBlock.BackgroundProperty, item.TargetProperty);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class CapturedTargets
|
||||
{
|
||||
public List<(object TargetObject, object TargetProperty)> Targets { get; } = [];
|
||||
}
|
||||
|
||||
public class CapturingTargetsMarkupExtension
|
||||
{
|
||||
public object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
var parentsProvider = serviceProvider.GetRequiredService<IProvideValueTarget>();
|
||||
var capturedTargets = AvaloniaLocator.Current.GetRequiredService<CapturedTargets>();
|
||||
capturedTargets.Targets.Add((parentsProvider.TargetObject, parentsProvider.TargetProperty));
|
||||
return Brushes.DarkViolet;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче