Browse Source

Merge pull request #11008 from AvaloniaUI/fixes/10946-dont-allow-items-binding

Make binding to `ItemsControl.Items` a compile error.
Max Katz 2 years ago
parent
commit
37ef8b7eb8

+ 13 - 3
src/Avalonia.Controls/Flyouts/Flyout.cs

@@ -13,12 +13,22 @@ namespace Avalonia.Controls
         public static readonly StyledProperty<object> ContentProperty =
             AvaloniaProperty.Register<Flyout, object>(nameof(Content));
 
+        private Classes? _classes;
+
         /// <summary>
         /// Gets the Classes collection to apply to the FlyoutPresenter this Flyout is hosting
         /// </summary>
-        public Classes FlyoutPresenterClasses => _classes ??= new Classes();
-
-        private Classes? _classes;
+        public Classes FlyoutPresenterClasses
+        {
+            get => _classes ??= new Classes();
+            set
+            {
+                if (_classes is null)
+                    _classes = value;
+                else if (_classes != value)
+                    _classes.Replace(value);
+            }
+        }
 
         /// <summary>
         /// Defines the <see cref="FlyoutPresenterTheme"/> property.

+ 2 - 1
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs

@@ -65,7 +65,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
                 {
                     AllowMultiple = true,
                     AllowXNull = allowNull,
-                    AllowRuntimeNull = allowNull
+                    AllowRuntimeNull = allowNull,
+                    AllowAttributeSyntax = false,
                 };
             }
 

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDesignPropertiesTransformer.cs

@@ -37,7 +37,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
                             on.Children[c] = new XamlAstXamlPropertyValueNode(ch,
                                 new XamlAstNamePropertyReference(ch,
                                     new XamlAstXmlTypeReference(ch, AvaloniaNs, "Design"),
-                                    mapTo, on.Type), directive.Values);
+                                    mapTo, on.Type), directive.Values, true);
                             c++;
                         }
                     }

+ 2 - 1
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XDataTypeTransformer.cs

@@ -52,7 +52,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
                                 new XamlAstNamePropertyReference(d,
                                     new XamlAstClrTypeReference(ch, declaringType, false), dataTypeProperty.Name,
                                     on.Type),
-                                d.Values);
+                                d.Values,
+                                true);
                         }
                     }
                 }

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XNameTransformer.cs

@@ -24,7 +24,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
 
                         on.Children[c] = new XamlAstXamlPropertyValueNode(d,
                             new XamlAstNamePropertyReference(d, on.Type, "Name", on.Type),
-                            d.Values);
+                            d.Values, true);
                 }
             }
 

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github

@@ -1 +1 @@
-Subproject commit 5e498f8bcca403a34aff5efc825cbb4e12b7fa8e
+Subproject commit 5dd0b042e144e677638224c49fec16dab66143e8

+ 2 - 2
src/tools/Avalonia.Generators/Compiler/NameDirectiveTransformer.cs

@@ -20,9 +20,9 @@ internal class NameDirectiveTransformer : IXamlAstTransformer
                 objectNode.Children[index] = new XamlAstXamlPropertyValueNode(
                     directive,
                     new XamlAstNamePropertyReference(directive, objectNode.Type, "Name", objectNode.Type),
-                    directive.Values);
+                    directive.Values, true);
         }
 
         return node;
     }
-}
+}

+ 27 - 1
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

@@ -910,7 +910,33 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
             Assert.Equal("World", target.Test2);
             Assert.Equal("Hello", target.Test1);
         }
-        
+
+        [Fact]
+        public void Can_Specify_Button_Classes()
+        {
+            var xaml = "<Button xmlns='https://github.com/avaloniaui' Classes='foo bar'/>";
+            var target = (Button)AvaloniaRuntimeXamlLoader.Load(xaml);
+
+            Assert.Equal(new[] { "foo", "bar" }, target.Classes);
+        }
+
+        [Fact]
+        public void Can_Specify_Flyout_FlyoutPresenterClasses()
+        {
+            var xaml = "<Flyout xmlns='https://github.com/avaloniaui' FlyoutPresenterClasses='foo bar'/>";
+            var target = (Flyout)AvaloniaRuntimeXamlLoader.Load(xaml);
+
+            Assert.Equal(new[] { "foo", "bar" }, target.FlyoutPresenterClasses);
+        }
+
+        [Fact]
+        public void Trying_To_Bind_ItemsControl_Items_Throws()
+        {
+            var xaml = "<ItemsControl xmlns='https://github.com/avaloniaui' Items='{Binding}'/>";
+
+            Assert.ThrowsAny<XmlException>(() => AvaloniaRuntimeXamlLoader.Load(xaml));
+        }
+
         private class SelectedItemsViewModel : INotifyPropertyChanged
         {
             public string[] Items { get; set; }