Browse Source

Merge branch 'master' into fixes/Consolidate-Package

pull/8196/head
Max Katz 4 years ago
committed by GitHub
parent
commit
0666bd1d46
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      Directory.Build.props
  2. 5
      build/AvaloniaPublicKey.props
  3. 3
      native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
  4. 18
      src/Avalonia.Base/Avalonia.Base.csproj
  5. 2
      src/Avalonia.Base/Collections/Pooled/PooledList.cs
  6. 40
      src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs
  7. 15
      src/Avalonia.Base/Metadata/DataTypeAttribute.cs
  8. 15
      src/Avalonia.Base/Properties/AssemblyInfo.cs
  9. 15
      src/Avalonia.Base/Utilities/WeakEvents.cs
  10. 5
      src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj
  11. 3
      src/Avalonia.Controls.ColorPicker/Properties/AssemblyInfo.cs
  12. 5
      src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj
  13. 4
      src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs
  14. 6
      src/Avalonia.Controls/Avalonia.Controls.csproj
  15. 5
      src/Avalonia.Controls/Properties/AssemblyInfo.cs
  16. 4
      src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj
  17. 4
      src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs
  18. 2
      src/Avalonia.PlatformSupport/Avalonia.PlatformSupport.csproj
  19. 5
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs
  20. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  21. 4
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  22. 3
      src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs
  23. 1
      src/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cs
  24. 1
      src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs
  25. 4
      src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
  26. 3
      src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs
  27. 9
      src/Skia/Avalonia.Skia/Avalonia.Skia.csproj
  28. 5
      src/Skia/Avalonia.Skia/Properties/AssemblyInfo.cs
  29. 10
      src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj
  30. 4
      src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs
  31. 18
      src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs
  32. 6
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs
  33. 95
      tests/Avalonia.LeakTests/ControlTests.cs
  34. 122
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs

1
Directory.Build.props

@ -1,4 +1,5 @@
<Project>
<Import Project="$(MSBuildThisFileDirectory)/build/AvaloniaPublicKey.props"/>
<PropertyGroup>
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)build-intermediate/nuget</PackageOutputPath>
<AvaloniaPreviewerNetCoreToolPath>$(MSBuildThisFileDirectory)\src\tools\Avalonia.Designer.HostApp\bin\$(Configuration)\netcoreapp2.0\Avalonia.Designer.HostApp.dll</AvaloniaPreviewerNetCoreToolPath>

5
build/AvaloniaPublicKey.props

@ -0,0 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AvaloniaPublicKey>0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87</AvaloniaPublicKey>
</PropertyGroup>
</Project>

3
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm

@ -296,6 +296,7 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso
if(Window != nullptr) {
[Window setContentSize:lastSize];
[Window invalidateShadow];
}
}
@finally {
@ -583,6 +584,8 @@ void WindowBaseImpl::InitialiseNSWindow() {
[Window setContentMaxSize:lastMaxSize];
[Window setOpaque:false];
[Window invalidateShadow];
if (lastMenu != nullptr) {
[GetWindowProtocol() applyMenu:lastMenu];

18
src/Avalonia.Base/Avalonia.Base.csproj

@ -17,4 +17,22 @@
<Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\DevAnalyzers.props" />
<Import Project="..\..\build\SourceGenerators.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Base.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.ColorPicker, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.DataGrid, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.DesignerSupport, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Direct2D1.RenderTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.LeakTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.Xaml.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.PlatformSupport, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Skia.RenderTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Skia.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Web.Blazor, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"/>
</ItemGroup>
</Project>

2
src/Avalonia.Base/Collections/Pooled/PooledList.cs

@ -587,7 +587,7 @@ namespace Avalonia.Collections.Pooled
if (size > 0 && _clearOnFree)
{
// Clear the elements so that the gc can reclaim the references.
Array.Clear(_items, 0, _size);
Array.Clear(_items, 0, size);
}
}

40
src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs

@ -1,5 +1,6 @@
using System;
using System.Runtime.ExceptionServices;
using Avalonia.Utilities;
namespace Avalonia.Data.Core.Plugins
{
@ -60,11 +61,10 @@ namespace Avalonia.Data.Core.Plugins
return AvaloniaPropertyRegistry.Instance.FindRegistered(o, propertyName);
}
private class Accessor : PropertyAccessorBase, IObserver<object?>
private class Accessor : PropertyAccessorBase, IWeakEventSubscriber<AvaloniaPropertyChangedEventArgs>
{
private readonly WeakReference<AvaloniaObject> _reference;
private readonly AvaloniaProperty _property;
private IDisposable? _subscription;
public Accessor(WeakReference<AvaloniaObject> reference, AvaloniaProperty property)
{
@ -95,29 +95,45 @@ namespace Avalonia.Data.Core.Plugins
return false;
}
protected override void SubscribeCore()
void IWeakEventSubscriber<AvaloniaPropertyChangedEventArgs>.
OnEvent(object? notifyPropertyChanged, WeakEvent ev, AvaloniaPropertyChangedEventArgs e)
{
_subscription = Instance?.GetObservable(_property).Subscribe(this);
if (e.Property == _property)
{
SendCurrentValue();
}
}
protected override void UnsubscribeCore()
protected override void SubscribeCore()
{
_subscription?.Dispose();
_subscription = null;
SubscribeToChanges();
SendCurrentValue();
}
void IObserver<object?>.OnCompleted()
protected override void UnsubscribeCore()
{
var instance = Instance;
if (instance != null)
WeakEvents.AvaloniaPropertyChanged.Unsubscribe(instance, this);
}
void IObserver<object?>.OnError(Exception error)
private void SendCurrentValue()
{
ExceptionDispatchInfo.Capture(error).Throw();
try
{
var value = Value;
PublishValue(value);
}
catch { }
}
void IObserver<object?>.OnNext(object? value)
private void SubscribeToChanges()
{
PublishValue(value);
var instance = Instance;
if (instance != null)
WeakEvents.AvaloniaPropertyChanged.Subscribe(instance, this);
}
}
}

15
src/Avalonia.Base/Metadata/DataTypeAttribute.cs

@ -0,0 +1,15 @@
using System;
namespace Avalonia.Metadata;
/// <summary>
/// Defines the property that contains type that should be used as a type information for compiled bindings.
/// </summary>
/// <remarks>
/// Used on DataTemplate.DataType property so it can be inherited in compiled bindings inside of the template.
/// </remarks>
[AttributeUsage(AttributeTargets.Property)]
public class DataTypeAttribute : Attribute
{
}

15
src/Avalonia.Base/Properties/AssemblyInfo.cs

@ -17,18 +17,3 @@ using Avalonia.Metadata;
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media.Transformation")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Styling")]
[assembly: InternalsVisibleTo("Avalonia.Base.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Controls, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Controls.ColorPicker, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Controls.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.LeakTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Markup.Xaml.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.PlatformSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Skia.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Web.Blazor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

15
src/Avalonia.Base/Utilities/WeakEvents.cs

@ -31,10 +31,23 @@ public class WeakEvents
return () => s.PropertyChanged -= handler;
});
/// <summary>
/// Represents PropertyChanged event from <see cref="AvaloniaObject"/>
/// </summary>
public static readonly WeakEvent<AvaloniaObject, AvaloniaPropertyChangedEventArgs>
AvaloniaPropertyChanged = WeakEvent.Register<AvaloniaObject, AvaloniaPropertyChangedEventArgs>(
(s, h) =>
{
EventHandler<AvaloniaPropertyChangedEventArgs> handler = (_, e) => h(s, e);
s.PropertyChanged += handler;
return () => s.PropertyChanged -= handler;
});
/// <summary>
/// Represents CanExecuteChanged event from <see cref="ICommand"/>
/// </summary>
public static readonly WeakEvent<ICommand, EventArgs> CommandCanExecuteChanged =
WeakEvent.Register<ICommand>((s, h) => s.CanExecuteChanged += h,
(s, h) => s.CanExecuteChanged -= h);
}
}

5
src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj

@ -22,4 +22,9 @@
<!--<Import Project="..\..\build\ApiDiff.props" />-->
<Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.DesignerSupport, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

3
src/Avalonia.Controls.ColorPicker/Properties/AssemblyInfo.cs

@ -1,8 +1,5 @@
using System.Runtime.CompilerServices;
using Avalonia.Metadata;
[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Collections")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Primitives")]

5
src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj

@ -18,4 +18,9 @@
<Import Project="..\..\build\BuildTargets.targets" />
<Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Controls.DataGrid.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.DesignerSupport, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

4
src/Avalonia.Controls.DataGrid/Properties/AssemblyInfo.cs

@ -1,9 +1,5 @@
using System.Runtime.CompilerServices;
using Avalonia.Metadata;
[assembly: InternalsVisibleTo("Avalonia.Controls.DataGrid.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Collections")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Primitives")]

6
src/Avalonia.Controls/Avalonia.Controls.csproj

@ -14,4 +14,10 @@
<Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Controls.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.DesignerSupport, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.LeakTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

5
src/Avalonia.Controls/Properties/AssemblyInfo.cs

@ -1,10 +1,5 @@
using System.Runtime.CompilerServices;
using Avalonia.Metadata;
[assembly: InternalsVisibleTo("Avalonia.Controls.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.DesignerSupport, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.LeakTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Automation")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]

4
src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj

@ -8,5 +8,7 @@
<ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" />
<PackageReference Include="Tmds.DBus" Version="0.9.0" />
</ItemGroup>
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.X11, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

4
src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs

@ -12,10 +12,6 @@ using Tmds.DBus;
[assembly: InternalsVisibleTo(Connection.DynamicAssemblyName)]
[assembly:
InternalsVisibleTo(
"Avalonia.X11, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
namespace Avalonia.FreeDesktop
{
internal class DBusTrayIconImpl : ITrayIconImpl

2
src/Avalonia.PlatformSupport/Avalonia.PlatformSupport.csproj

@ -18,7 +18,7 @@
<Import Project="..\..\build\NullableEnable.props" />
<ItemGroup>
<InternalsVisibleTo Include="$(AssemblyName).UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87" />
<InternalsVisibleTo Include="$(AssemblyName).UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
</ItemGroup>
</Project>

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

@ -49,6 +49,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
}
else if (child is XamlPropertyAssignmentNode pa)
{
var templateDataTypeAttribute = context.GetAvaloniaTypes().DataTypeAttribute;
if (pa.Property.Name == "DataContext"
&& pa.Property.DeclaringType.Equals(context.GetAvaloniaTypes().StyledElement)
&& pa.Values[0] is XamlMarkupExtensionNode ext
@ -56,8 +58,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
{
inferredDataContextTypeNode = ParseDataContext(context, on, obj);
}
else if(context.GetAvaloniaTypes().DataTemplate.IsAssignableFrom(on.Type.GetClrType())
&& pa.Property.Name == "DataType"
else if(pa.Property.CustomAttributes.Any(a => a.Type == templateDataTypeAttribute)
&& pa.Values[0] is XamlTypeExtensionNode dataTypeNode)
{
inferredDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on, dataTypeNode.Value.GetClrType());

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@ -26,6 +26,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType Transitions { get; }
public IXamlType AssignBindingAttribute { get; }
public IXamlType DependsOnAttribute { get; }
public IXamlType DataTypeAttribute { get; }
public IXamlType UnsetValueType { get; }
public IXamlType StyledElement { get; }
public IXamlType IStyledElement { get; }
@ -112,6 +113,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
Transitions = cfg.TypeSystem.GetType("Avalonia.Animation.Transitions");
AssignBindingAttribute = cfg.TypeSystem.GetType("Avalonia.Data.AssignBindingAttribute");
DependsOnAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.DependsOnAttribute");
DataTypeAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.DataTypeAttribute");
AvaloniaObjectBindMethod = AvaloniaObjectExtensions.FindMethod("Bind", IDisposable, false, IAvaloniaObject,
AvaloniaProperty,
IBinding, cfg.WellKnownTypes.Object);

4
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -63,4 +63,8 @@
<Import Project="..\..\..\build\Rx.props" />
<Import Project="..\..\..\build\ApiDiff.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Markup.Xaml.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

3
src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs

@ -1,9 +1,6 @@
using Avalonia.Metadata;
using System.Runtime.CompilerServices;
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.MarkupExtensions")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.Styling")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.Templates")]
[assembly: InternalsVisibleTo("Avalonia.Markup.Xaml.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]

1
src/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cs

@ -7,6 +7,7 @@ namespace Avalonia.Markup.Xaml.Templates
{
public class DataTemplate : IRecyclingDataTemplate
{
[DataType]
public Type DataType { get; set; }
[Content]

1
src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs

@ -11,6 +11,7 @@ namespace Avalonia.Markup.Xaml.Templates
{
public class TreeDataTemplate : ITreeDataTemplate
{
[DataType]
public Type DataType { get; set; }
[Content]

4
src/Markup/Avalonia.Markup/Avalonia.Markup.csproj

@ -17,4 +17,8 @@
<Import Project="..\..\..\build\ApiDiff.props" />
<Import Project="..\..\..\build\NullableEnable.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Markup.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
</Project>

3
src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs

@ -1,8 +1,5 @@
using Avalonia.Metadata;
using System.Runtime.CompilerServices;
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Data")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Data")]
[assembly: InternalsVisibleTo("Avalonia.Markup.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]

9
src/Skia/Avalonia.Skia/Avalonia.Skia.csproj

@ -18,4 +18,13 @@
<Import Project="..\..\..\build\SkiaSharp.props" />
<Import Project="..\..\..\build\HarfBuzzSharp.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Skia.RenderTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Skia.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>

5
src/Skia/Avalonia.Skia/Properties/AssemblyInfo.cs

@ -1,5 +0,0 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Skia.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]

10
src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj

@ -19,4 +19,14 @@
<Import Project="..\..\..\build\HarfBuzzSharp.props" />
<Import Project="..\..\..\build\JetBrains.Annotations.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Direct2D1.RenderTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Direct2D1.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>

4
src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs

@ -1,4 +0,0 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]
[assembly: InternalsVisibleTo("Avalonia.Direct2D1.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87")]

18
src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs

@ -37,6 +37,24 @@ namespace Avalonia.Win32.Input
IsComposing = false;
}
public void ClearLanguageAndWindow()
{
if (HWND != IntPtr.Zero && _defaultImc != IntPtr.Zero)
{
ImmReleaseContext(HWND, _defaultImc);
}
_defaultImc = IntPtr.Zero;
HWND = IntPtr.Zero;
_parent = null;
_active = false;
_langId = 0;
_showCompositionWindow = false;
_showCandidateList = false;
IsComposing = false;
}
//Dependant on CurrentThread. When Avalonia will support Multiple Dispatchers -
//every Dispatcher should have their own InputMethod.
public static Imm32InputMethod Current { get; } = new Imm32InputMethod();

6
src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

@ -82,6 +82,12 @@ namespace Avalonia.Win32
case WindowsMessage.WM_DESTROY:
{
UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, IntPtr.Zero, IntPtr.Zero, null);
// We need to release IMM context and state to avoid leaks.
if (Imm32InputMethod.Current.HWND == _hwnd)
{
Imm32InputMethod.Current.ClearLanguageAndWindow();
}
//Window doesn't exist anymore
_hwnd = IntPtr.Zero;

95
tests/Avalonia.LeakTests/ControlTests.cs

@ -2,17 +2,18 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Diagnostics;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Styling;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using JetBrains.dotMemoryUnit;
@ -661,14 +662,96 @@ namespace Avalonia.LeakTests
}
}
[Fact]
public void ElementName_Binding_In_DataTemplate_Is_Freed()
{
using (Start())
{
var items = new ObservableCollection<int>(Enumerable.Range(0, 10));
NameScope ns;
TextBox tb;
ListBox lb;
var window = new Window
{
[NameScope.NameScopeProperty] = ns = new NameScope(),
Width = 100,
Height = 100,
Content = new StackPanel
{
Children =
{
(tb = new TextBox
{
Name = "tb",
Text = "foo",
}),
(lb = new ListBox
{
Items = items,
ItemTemplate = new FuncDataTemplate<int>((_, _) =>
new Canvas
{
Width = 10,
Height = 10,
[!Control.TagProperty] = new Binding
{
ElementName = "tb",
Path = "Text",
NameScope = new WeakReference<INameScope>(ns),
}
})
}),
}
}
};
tb.RegisterInNameScope(ns);
window.Show();
window.LayoutManager.ExecuteInitialLayoutPass();
void AssertInitialItemState()
{
var item0 = (ListBoxItem)lb.ItemContainerGenerator.Containers.First().ContainerControl;
var canvas0 = (Canvas)item0.Presenter.Child;
Assert.Equal("foo", canvas0.Tag);
}
Assert.Equal(10, lb.ItemContainerGenerator.Containers.Count());
AssertInitialItemState();
items.Clear();
window.LayoutManager.ExecuteLayoutPass();
Assert.Empty(lb.ItemContainerGenerator.Containers);
dotMemory.Check(memory =>
Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Canvas>()).ObjectsCount));
}
}
private IDisposable Start()
{
return UnitTestApplication.Start(TestServices.StyledWindow.With(
focusManager: new FocusManager(),
keyboardDevice: () => new KeyboardDevice(),
inputManager: new InputManager()));
void Cleanup()
{
// KeyboardDevice holds a reference to the focused item.
KeyboardDevice.Instance.SetFocusedElement(null, NavigationMethod.Unspecified, KeyModifiers.None);
// Empty the dispatcher queue.
Dispatcher.UIThread.RunJobs();
}
return new CompositeDisposable
{
Disposable.Create(Cleanup),
UnitTestApplication.Start(TestServices.StyledWindow.With(
focusManager: new FocusManager(),
keyboardDevice: () => new KeyboardDevice(),
inputManager: new InputManager()))
};
}
private class Node
{
public string Name { get; set; }

122
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs

@ -8,11 +8,14 @@ using System.Text;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data.Converters;
using Avalonia.Data.Core;
using Avalonia.Input;
using Avalonia.Markup.Data;
using Avalonia.Markup.Xaml.Templates;
using Avalonia.Media;
using Avalonia.Metadata;
using Avalonia.UnitTests;
using XamlX;
using Xunit;
@ -455,7 +458,106 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
ThrowsXamlTransformException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
}
}
[Fact]
public void IgnoresDataTemplateTypeFromDataTypePropertyIfXDataTypeDefined()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
<Window.DataTemplates>
<DataTemplate DataType='local:TestDataContextBaseClass' x:DataType='local:TestDataContext'>
<TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
</DataTemplate>
</Window.DataTemplates>
<ContentControl x:DataType='local:TestDataContext' Name='target' Content='{CompiledBinding}' />
</Window>";
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
var target = window.FindControl<ContentControl>("target");
var dataContext = new TestDataContext();
dataContext.StringProperty = "Initial Value";
window.DataContext = dataContext;
window.ApplyTemplate();
target.ApplyTemplate();
((ContentPresenter)target.Presenter).UpdateChild();
Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
}
}
[Fact]
public void InfersCustomDataTemplateBasedOnAttribute()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
<Window.DataTemplates>
<local:CustomDataTemplate FancyDataType='local:TestDataContext'>
<TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
</local:CustomDataTemplate>
</Window.DataTemplates>
<ContentControl x:DataType='local:TestDataContext' Name='target' Content='{CompiledBinding}' />
</Window>";
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
var target = window.FindControl<ContentControl>("target");
var dataContext = new TestDataContext();
dataContext.StringProperty = "Initial Value";
window.DataContext = dataContext;
window.ApplyTemplate();
target.ApplyTemplate();
((ContentPresenter)target.Presenter).UpdateChild();
Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
}
}
[Fact]
public void InfersCustomDataTemplateBasedOnAttributeFromBaseClass()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'>
<Window.DataTemplates>
<local:CustomDataTemplateInherit FancyDataType='local:TestDataContext'>
<TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
</local:CustomDataTemplateInherit>
</Window.DataTemplates>
<ContentControl x:DataType='local:TestDataContext' Name='target' Content='{CompiledBinding}' />
</Window>";
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
var target = window.FindControl<ContentControl>("target");
var dataContext = new TestDataContext();
dataContext.StringProperty = "Initial Value";
window.DataContext = dataContext;
window.ApplyTemplate();
target.ApplyTemplate();
((ContentPresenter)target.Presenter).UpdateChild();
Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
}
}
[Fact]
public void ResolvesElementNameBinding()
{
@ -1324,7 +1426,9 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
public string StringProperty { get; set; }
}
public class TestDataContext : IHasPropertyDerived
public class TestDataContextBaseClass {}
public class TestDataContext : TestDataContextBaseClass, IHasPropertyDerived
{
public string StringProperty { get; set; }
@ -1413,4 +1517,20 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
return ReferenceEquals(null, parameter) == false;
}
}
public class CustomDataTemplate : IDataTemplate
{
[DataType]
public Type FancyDataType { get; set; }
[Content]
[TemplateContent]
public object Content { get; set; }
public bool Match(object data) => FancyDataType.IsInstanceOfType(data);
public IControl Build(object data) => TemplateContent.Load(Content)?.Control;
}
public class CustomDataTemplateInherit : CustomDataTemplate { }
}

Loading…
Cancel
Save