|
|
@ -3,22 +3,23 @@ using System.Collections.Generic; |
|
|
using System.Collections.ObjectModel; |
|
|
using System.Collections.ObjectModel; |
|
|
using System.ComponentModel; |
|
|
using System.ComponentModel; |
|
|
using System.Globalization; |
|
|
using System.Globalization; |
|
|
|
|
|
using System.Linq; |
|
|
using System.Reactive.Subjects; |
|
|
using System.Reactive.Subjects; |
|
|
using System.Text; |
|
|
|
|
|
using System.Threading.Tasks; |
|
|
using System.Threading.Tasks; |
|
|
using Avalonia.Controls; |
|
|
using Avalonia.Controls; |
|
|
using Avalonia.Controls.Presenters; |
|
|
using Avalonia.Controls.Presenters; |
|
|
using Avalonia.Controls.Templates; |
|
|
using Avalonia.Controls.Templates; |
|
|
|
|
|
using Avalonia.Data; |
|
|
using Avalonia.Data.Converters; |
|
|
using Avalonia.Data.Converters; |
|
|
using Avalonia.Data.Core; |
|
|
using Avalonia.Data.Core; |
|
|
using Avalonia.Input; |
|
|
using Avalonia.Input; |
|
|
using Avalonia.Markup.Data; |
|
|
using Avalonia.Markup.Data; |
|
|
|
|
|
using Avalonia.Markup.Xaml.MarkupExtensions; |
|
|
|
|
|
using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings; |
|
|
using Avalonia.Markup.Xaml.Templates; |
|
|
using Avalonia.Markup.Xaml.Templates; |
|
|
using Avalonia.Media; |
|
|
using Avalonia.Media; |
|
|
using Avalonia.Metadata; |
|
|
using Avalonia.Metadata; |
|
|
using Avalonia.UnitTests; |
|
|
using Avalonia.UnitTests; |
|
|
using JetBrains.Annotations; |
|
|
|
|
|
using XamlX; |
|
|
|
|
|
using Xunit; |
|
|
using Xunit; |
|
|
|
|
|
|
|
|
namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
@ -102,6 +103,91 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
Assert.Equal(dataContext.StringProperty, textBlock.Text); |
|
|
Assert.Equal(dataContext.StringProperty, textBlock.Text); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void ResolvesPathPassedByPropertyWithInnerItemTemplate() |
|
|
|
|
|
{ |
|
|
|
|
|
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' |
|
|
|
|
|
x:DataType='local:TestDataContext'> |
|
|
|
|
|
<ItemsControl Name='itemsControl' Items='{CompiledBinding Path=ListProperty}'> |
|
|
|
|
|
<ItemsControl.ItemTemplate> |
|
|
|
|
|
<DataTemplate> |
|
|
|
|
|
<TextBlock /> |
|
|
|
|
|
</DataTemplate> |
|
|
|
|
|
</ItemsControl.ItemTemplate> |
|
|
|
|
|
</ItemsControl> |
|
|
|
|
|
</Window>";
|
|
|
|
|
|
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); |
|
|
|
|
|
var textBlock = window.FindControl<ItemsControl>("itemsControl"); |
|
|
|
|
|
|
|
|
|
|
|
var dataContext = new TestDataContext |
|
|
|
|
|
{ |
|
|
|
|
|
ListProperty = |
|
|
|
|
|
{ |
|
|
|
|
|
"Hello" |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
window.DataContext = dataContext; |
|
|
|
|
|
|
|
|
|
|
|
Assert.Equal(dataContext.ListProperty, textBlock.Items); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void ResolvesDataTypeFromBindingProperty() |
|
|
|
|
|
{ |
|
|
|
|
|
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'> |
|
|
|
|
|
<TextBlock Text='{CompiledBinding StringProperty, DataType=local:TestDataContext}' Name='textBlock' /> |
|
|
|
|
|
</Window>";
|
|
|
|
|
|
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); |
|
|
|
|
|
var textBlock = window.FindControl<TextBlock>("textBlock"); |
|
|
|
|
|
|
|
|
|
|
|
var dataContext = new TestDataContext |
|
|
|
|
|
{ |
|
|
|
|
|
StringProperty = "foobar" |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
window.DataContext = dataContext; |
|
|
|
|
|
|
|
|
|
|
|
Assert.Equal(dataContext.StringProperty, textBlock.Text); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void ResolvesDataTypeFromBindingProperty_TypeExtension() |
|
|
|
|
|
{ |
|
|
|
|
|
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'> |
|
|
|
|
|
<TextBlock Text='{CompiledBinding StringProperty, DataType={x:Type local:TestDataContext}}' Name='textBlock' /> |
|
|
|
|
|
</Window>";
|
|
|
|
|
|
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); |
|
|
|
|
|
var textBlock = window.FindControl<TextBlock>("textBlock"); |
|
|
|
|
|
|
|
|
|
|
|
var dataContext = new TestDataContext |
|
|
|
|
|
{ |
|
|
|
|
|
StringProperty = "foobar" |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
window.DataContext = dataContext; |
|
|
|
|
|
|
|
|
|
|
|
Assert.Equal(dataContext.StringProperty, textBlock.Text); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
[Fact] |
|
|
[Fact] |
|
|
public void ResolvesStreamTaskBindingCorrectly() |
|
|
public void ResolvesStreamTaskBindingCorrectly() |
|
|
@ -641,6 +727,64 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void ResolvesRelativeSourceBindingFromTemplate() |
|
|
|
|
|
{ |
|
|
|
|
|
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|
|
|
|
|
{ |
|
|
|
|
|
var xaml = @"
|
|
|
|
|
|
<ContentControl xmlns='https://github.com/avaloniaui'
|
|
|
|
|
|
Content='Hello'> |
|
|
|
|
|
<ContentControl.Styles> |
|
|
|
|
|
<Style Selector='ContentControl'> |
|
|
|
|
|
<Setter Property='Template'> |
|
|
|
|
|
<ControlTemplate> |
|
|
|
|
|
<ContentPresenter Content='{CompiledBinding Content, RelativeSource={RelativeSource TemplatedParent}}' /> |
|
|
|
|
|
</ControlTemplate> |
|
|
|
|
|
</Setter> |
|
|
|
|
|
</Style> |
|
|
|
|
|
</ContentControl.Styles> |
|
|
|
|
|
</ContentControl>";
|
|
|
|
|
|
|
|
|
|
|
|
var contentControl = AvaloniaRuntimeXamlLoader.Parse<ContentControl>(xaml); |
|
|
|
|
|
contentControl.Measure(new Size(10, 10)); |
|
|
|
|
|
|
|
|
|
|
|
var result = contentControl.GetTemplateChildren().OfType<ContentPresenter>().First(); |
|
|
|
|
|
Assert.Equal("Hello", result.Content); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void ResolvesElementNameInTemplate() |
|
|
|
|
|
{ |
|
|
|
|
|
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|
|
|
|
|
{ |
|
|
|
|
|
var xaml = @"
|
|
|
|
|
|
<ContentControl xmlns='https://github.com/avaloniaui'
|
|
|
|
|
|
Content='Hello'> |
|
|
|
|
|
<ContentControl.Styles> |
|
|
|
|
|
<Style Selector='ContentControl'> |
|
|
|
|
|
<Setter Property='Template'> |
|
|
|
|
|
<ControlTemplate> |
|
|
|
|
|
<Panel> |
|
|
|
|
|
<TextBox Name='InnerTextBox' Text='Hello' /> |
|
|
|
|
|
<ContentPresenter Content='{CompiledBinding Text, ElementName=InnerTextBox}' /> |
|
|
|
|
|
</Panel> |
|
|
|
|
|
</ControlTemplate> |
|
|
|
|
|
</Setter> |
|
|
|
|
|
</Style> |
|
|
|
|
|
</ContentControl.Styles> |
|
|
|
|
|
</ContentControl>";
|
|
|
|
|
|
|
|
|
|
|
|
var contentControl = AvaloniaRuntimeXamlLoader.Parse<ContentControl>(xaml); |
|
|
|
|
|
contentControl.Measure(new Size(10, 10)); |
|
|
|
|
|
|
|
|
|
|
|
var result = contentControl.GetTemplateChildren().OfType<ContentPresenter>().First(); |
|
|
|
|
|
|
|
|
|
|
|
Assert.Equal("Hello", result.Content); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
[Fact] |
|
|
[Fact] |
|
|
public void Binds_To_Source() |
|
|
public void Binds_To_Source() |
|
|
{ |
|
|
{ |
|
|
@ -1145,6 +1289,28 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
Assert.Equal("bar-" + typeof(TestDataContext).FullName, textBlock.Text); |
|
|
Assert.Equal("bar-" + typeof(TestDataContext).FullName, textBlock.Text); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void SupportCastToTypeInExpressionWithProperty_ExplicitPropertyCast() |
|
|
|
|
|
{ |
|
|
|
|
|
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|
|
|
|
|
{ |
|
|
|
|
|
var xaml = @"
|
|
|
|
|
|
<Window xmlns='https://github.com/avaloniaui'
|
|
|
|
|
|
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
|
|
|
|
|
|
xmlns:local='using:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions'> |
|
|
|
|
|
<ContentControl Content='{CompiledBinding $parent.((local:IHasExplicitProperty)DataContext).ExplicitProperty}' Name='contentControl' /> |
|
|
|
|
|
</Window>";
|
|
|
|
|
|
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); |
|
|
|
|
|
var contentControl = window.GetControl<ContentControl>("contentControl"); |
|
|
|
|
|
|
|
|
|
|
|
var dataContext = new TestDataContext(); |
|
|
|
|
|
|
|
|
|
|
|
window.DataContext = dataContext; |
|
|
|
|
|
|
|
|
|
|
|
Assert.Equal(((IHasExplicitProperty)dataContext).ExplicitProperty, contentControl.Content); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
[Fact] |
|
|
[Fact] |
|
|
public void Binds_To_Self_Without_DataType() |
|
|
public void Binds_To_Self_Without_DataType() |
|
|
@ -1366,6 +1532,43 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void ResolvesDataTypeForAssignBinding() |
|
|
|
|
|
{ |
|
|
|
|
|
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|
|
|
|
|
{ |
|
|
|
|
|
var xaml = @"
|
|
|
|
|
|
<local:AssignBindingControl 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' |
|
|
|
|
|
x:DataType='local:TestDataContext' |
|
|
|
|
|
X='{CompiledBinding StringProperty}' />";
|
|
|
|
|
|
var control = (AssignBindingControl)AvaloniaRuntimeXamlLoader.Load(xaml); |
|
|
|
|
|
var compiledPath = ((CompiledBindingExtension)control.X).Path; |
|
|
|
|
|
|
|
|
|
|
|
var node = Assert.IsType<PropertyElement>(Assert.Single(compiledPath.Elements)); |
|
|
|
|
|
Assert.Equal(typeof(string), node.Property.PropertyType); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void ResolvesDataTypeForAssignBinding_FromBindingProperty() |
|
|
|
|
|
{ |
|
|
|
|
|
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|
|
|
|
|
{ |
|
|
|
|
|
var xaml = @"
|
|
|
|
|
|
<local:AssignBindingControl 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' |
|
|
|
|
|
X='{CompiledBinding StringProperty, DataType=local:TestDataContext}' />";
|
|
|
|
|
|
var control = (AssignBindingControl)AvaloniaRuntimeXamlLoader.Load(xaml); |
|
|
|
|
|
var compiledPath = ((CompiledBindingExtension)control.X).Path; |
|
|
|
|
|
|
|
|
|
|
|
var node = Assert.IsType<PropertyElement>(Assert.Single(compiledPath.Elements)); |
|
|
|
|
|
Assert.Equal(typeof(string), node.Property.PropertyType); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void Throws(string type, Action cb) |
|
|
void Throws(string type, Action cb) |
|
|
{ |
|
|
{ |
|
|
try |
|
|
try |
|
|
@ -1410,6 +1613,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
public interface IHasPropertyDerived : IHasProperty |
|
|
public interface IHasPropertyDerived : IHasProperty |
|
|
{ } |
|
|
{ } |
|
|
|
|
|
|
|
|
|
|
|
public interface IHasExplicitProperty |
|
|
|
|
|
{ |
|
|
|
|
|
string ExplicitProperty { get; } |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public class AppendConverter : IValueConverter |
|
|
public class AppendConverter : IValueConverter |
|
|
{ |
|
|
{ |
|
|
public static IValueConverter Instance { get; } = new AppendConverter(); |
|
|
public static IValueConverter Instance { get; } = new AppendConverter(); |
|
|
@ -1429,7 +1637,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
|
|
|
|
|
|
public class TestDataContextBaseClass {} |
|
|
public class TestDataContextBaseClass {} |
|
|
|
|
|
|
|
|
public class TestDataContext : TestDataContextBaseClass, IHasPropertyDerived |
|
|
public class TestDataContext : TestDataContextBaseClass, IHasPropertyDerived, IHasExplicitProperty |
|
|
{ |
|
|
{ |
|
|
public string StringProperty { get; set; } |
|
|
public string StringProperty { get; set; } |
|
|
|
|
|
|
|
|
@ -1449,6 +1657,10 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
|
|
|
|
|
|
public INonIntegerIndexerDerived NonIntegerIndexerInterfaceProperty => NonIntegerIndexerProperty; |
|
|
public INonIntegerIndexerDerived NonIntegerIndexerInterfaceProperty => NonIntegerIndexerProperty; |
|
|
|
|
|
|
|
|
|
|
|
string IHasExplicitProperty.ExplicitProperty => "Hello"; |
|
|
|
|
|
|
|
|
|
|
|
public string ExplicitProperty => "Bye"; |
|
|
|
|
|
|
|
|
public class NonIntegerIndexer : NotifyingBase, INonIntegerIndexerDerived |
|
|
public class NonIntegerIndexer : NotifyingBase, INonIntegerIndexerDerived |
|
|
{ |
|
|
{ |
|
|
private readonly Dictionary<string, string> _storage = new Dictionary<string, string>(); |
|
|
private readonly Dictionary<string, string> _storage = new Dictionary<string, string>(); |
|
|
@ -1534,4 +1746,9 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public class CustomDataTemplateInherit : CustomDataTemplate { } |
|
|
public class CustomDataTemplateInherit : CustomDataTemplate { } |
|
|
|
|
|
|
|
|
|
|
|
public class AssignBindingControl : Control |
|
|
|
|
|
{ |
|
|
|
|
|
[AssignBinding] public IBinding X { get; set; } |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|