diff --git a/src/Avalonia.Themes.Fluent/Accents/Base.xaml b/src/Avalonia.Themes.Fluent/Accents/Base.xaml
index 9cf2824c06..8358297f8b 100644
--- a/src/Avalonia.Themes.Fluent/Accents/Base.xaml
+++ b/src/Avalonia.Themes.Fluent/Accents/Base.xaml
@@ -12,8 +12,8 @@
#FF0066CC
#FFFFFFFF
#FF000000
- avares://Avalonia.Themes.Fluent/Assets#Lato
- 13
+ avares://Avalonia.Themes.Fluent/Assets#Roboto
+ 14
True
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Black.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Black.ttf
deleted file mode 100644
index e2aeb6cc35..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Black.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Bold.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Bold.ttf
deleted file mode 100644
index ef5ae3b43e..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Bold.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Hairline.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Hairline.ttf
deleted file mode 100644
index 4c5a8fdd99..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Hairline.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Heavy.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Heavy.ttf
deleted file mode 100644
index fc70ab7c35..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Heavy.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Italic.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Italic.ttf
deleted file mode 100644
index b23256ff53..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Italic.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Light.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Light.ttf
deleted file mode 100644
index 0809b8e6b5..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Light.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Medium.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Medium.ttf
deleted file mode 100644
index 2c612da2ae..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Medium.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Regular.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Regular.ttf
deleted file mode 100644
index adbfc467d2..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Regular.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Semibold.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Semibold.ttf
deleted file mode 100644
index 60ac82d65b..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Semibold.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Lato-Thin.ttf b/src/Avalonia.Themes.Fluent/Assets/Lato-Thin.ttf
deleted file mode 100644
index 0f84dc1b19..0000000000
Binary files a/src/Avalonia.Themes.Fluent/Assets/Lato-Thin.ttf and /dev/null differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Black.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Black.ttf
new file mode 100644
index 0000000000..38f809991d
Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Roboto-Black.ttf differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Bold.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Bold.ttf
new file mode 100644
index 0000000000..5fd9dd9eed
Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Roboto-Bold.ttf differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Light.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Light.ttf
new file mode 100644
index 0000000000..113d545eea
Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Roboto-Light.ttf differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Medium.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Medium.ttf
new file mode 100644
index 0000000000..98c4538462
Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Roboto-Medium.ttf differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Regular.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Regular.ttf
new file mode 100644
index 0000000000..c1c3700fe5
Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Roboto-Regular.ttf differ
diff --git a/src/Avalonia.Themes.Fluent/Assets/Roboto-Thin.ttf b/src/Avalonia.Themes.Fluent/Assets/Roboto-Thin.ttf
new file mode 100644
index 0000000000..04b15402d9
Binary files /dev/null and b/src/Avalonia.Themes.Fluent/Assets/Roboto-Thin.ttf differ
diff --git a/src/Avalonia.Themes.Fluent/Button.xaml b/src/Avalonia.Themes.Fluent/Button.xaml
index 561b84521d..34bcd0f0c1 100644
--- a/src/Avalonia.Themes.Fluent/Button.xaml
+++ b/src/Avalonia.Themes.Fluent/Button.xaml
@@ -81,7 +81,7 @@
-
+
diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs
index 1f527e9569..03ec32b9cf 100644
--- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlBindingPathHelper.cs
@@ -121,7 +121,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
}
else
{
- var clrProperty = targetType.GetAllProperties().FirstOrDefault(p => p.Name == propName.PropertyName);
+ var clrProperty = GetAllDefinedProperties(targetType).FirstOrDefault(p => p.Name == propName.PropertyName);
if (clrProperty is null)
{
@@ -139,15 +139,15 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
}
IXamlProperty property = null;
- for (var currentType = targetType; currentType != null; currentType = currentType.BaseType)
+ foreach (var currentType in TraverseTypeHierarchy(targetType))
{
var defaultMemberAttribute = currentType.CustomAttributes.FirstOrDefault(x => x.Type.Namespace == "System.Reflection" && x.Type.Name == "DefaultMemberAttribute");
if (defaultMemberAttribute != null)
{
- property = targetType.GetAllProperties().FirstOrDefault(x => x.Name == (string)defaultMemberAttribute.Parameters[0]);
+ property = currentType.GetAllProperties().FirstOrDefault(x => x.Name == (string)defaultMemberAttribute.Parameters[0]);
break;
}
- };
+ }
if (property is null)
{
throw new XamlX.XamlParseException($"The type '${targetType}' does not have an indexer.", lineInfo);
@@ -252,6 +252,39 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return TypeReferenceResolver.ResolveType(context, $"{ns}:{name}", false,
lineInfo, true).GetClrType();
}
+
+ static IEnumerable GetAllDefinedProperties(IXamlType type)
+ {
+ foreach (var t in TraverseTypeHierarchy(type))
+ {
+ foreach (var p in t.Properties)
+ {
+ yield return p;
+ }
+ }
+ }
+
+ static IEnumerable TraverseTypeHierarchy(IXamlType type)
+ {
+ if (type.IsInterface)
+ {
+ yield return type;
+ foreach (var iface in type.Interfaces)
+ {
+ foreach (var h in TraverseTypeHierarchy(iface))
+ {
+ yield return h;
+ }
+ }
+ }
+ else
+ {
+ for (var currentType = type; currentType != null; currentType = currentType.BaseType)
+ {
+ yield return currentType;
+ }
+ }
+ }
}
class ScopeRegistrationFinder : IXamlAstVisitor
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs
index 37aa123cfc..4e574f2b9e 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs
@@ -43,6 +43,33 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
}
}
+ [Fact]
+ public void ResolvesClrPropertyBasedOnDataContextType_InterfaceInheritance()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var xaml = @"
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = window.FindControl("textBlock");
+
+ var dataContext = new TestDataContext
+ {
+ StringProperty = "foobar"
+ };
+
+ window.DataContext = dataContext;
+
+ Assert.Equal(dataContext.StringProperty, textBlock.Text);
+ }
+ }
+
[Fact]
public void ResolvesPathPassedByProperty()
{
@@ -274,6 +301,36 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
}
}
+ [Fact]
+ public void ResolvesNonIntegerIndexerBindingFromParentInterfaceCorrectly()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var xaml = @"
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = window.FindControl("textBlock");
+
+ var dataContext = new TestDataContext();
+
+ dataContext.NonIntegerIndexerInterfaceProperty["Test"] = "Initial Value";
+
+ window.DataContext = dataContext;
+
+ Assert.Equal(dataContext.NonIntegerIndexerInterfaceProperty["Test"], textBlock.Text);
+
+ dataContext.NonIntegerIndexerInterfaceProperty["Test"] = "New Value";
+
+ Assert.Equal(dataContext.NonIntegerIndexerInterfaceProperty["Test"], textBlock.Text);
+ }
+ }
+
[Fact]
public void InfersDataTemplateTypeFromDataTypeProperty()
{
@@ -584,7 +641,23 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
}
}
- public class TestDataContext
+ public interface INonIntegerIndexer
+ {
+ string this[string key] {get; set;}
+ }
+
+ public interface INonIntegerIndexerDerived : INonIntegerIndexer
+ {}
+
+ public interface IHasProperty
+ {
+ string StringProperty {get; set; }
+ }
+
+ public interface IHasPropertyDerived : IHasProperty
+ {}
+
+ public class TestDataContext : IHasPropertyDerived
{
public string StringProperty { get; set; }
@@ -600,7 +673,9 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
public NonIntegerIndexer NonIntegerIndexerProperty { get; set; } = new NonIntegerIndexer();
- public class NonIntegerIndexer : NotifyingBase
+ public INonIntegerIndexerDerived NonIntegerIndexerInterfaceProperty => NonIntegerIndexerProperty;
+
+ public class NonIntegerIndexer : NotifyingBase, INonIntegerIndexerDerived
{
private readonly Dictionary _storage = new Dictionary();