Browse Source

Merge pull request #2515 from AvaloniaUI/fixes/2512-xaml-namescope-registration

Don't register controls with parent namescope.
pull/2580/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
40747cfcad
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.Controls/Primitives/TemplatedControl.cs
  2. 17
      src/Avalonia.Styling/StyledElement.cs
  3. 31
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/DataTemplateTests.cs
  4. 7
      tests/Avalonia.Styling.UnitTests/StyledElementTests.cs
  5. 23
      tests/Avalonia.Styling.UnitTests/StyledElementTests_NameScope.cs

2
src/Avalonia.Controls/Primitives/TemplatedControl.cs

@ -357,7 +357,7 @@ namespace Avalonia.Controls.Primitives
if (control.TemplatedParent == this) if (control.TemplatedParent == this)
{ {
foreach (IControl child in control.GetVisualChildren()) foreach (IControl child in control.GetLogicalChildren())
{ {
RegisterNames(child, nameScope); RegisterNames(child, nameScope);
} }

17
src/Avalonia.Styling/StyledElement.cs

@ -677,23 +677,6 @@ namespace Avalonia
if (Name != null) if (Name != null)
{ {
_nameScope?.Register(Name, this); _nameScope?.Register(Name, this);
var visualParent = Parent as StyledElement;
if (this is INameScope && visualParent != null)
{
// If we have e.g. a named UserControl in a window then we want that control
// to be findable by name from the Window, so register with both name scopes.
// This differs from WPF's behavior in that XAML manually registers controls
// with name scopes based on the XAML file in which the name attribute appears,
// but we're trying to avoid XAML magic in Avalonia in order to made code-
// created UIs easy. This will cause problems if a UserControl declares a name
// in its XAML and that control is included multiple times in a parent control
// (as the name will be duplicated), however at the moment I'm fine with saying
// "don't do that".
var parentNameScope = NameScope.FindNameScope(visualParent);
parentNameScope?.Register(Name, this);
}
} }
} }

31
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/DataTemplateTests.cs

@ -38,6 +38,37 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
} }
} }
[Fact]
public void DataTemplate_Can_Contain_Named_UserControl()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:sys='clr-namespace:System;assembly=mscorlib'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<ItemsControl Name='itemsControl' Items='{Binding}'>
<ItemsControl.ItemTemplate>
<DataTemplate>
<UserControl Name='foo'/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var itemsControl = window.FindControl<ItemsControl>("itemsControl");
window.DataContext = new[] { "item1", "item2" };
window.ApplyTemplate();
itemsControl.ApplyTemplate();
itemsControl.Presenter.ApplyTemplate();
Assert.Equal(2, itemsControl.Presenter.Panel.Children.Count);
}
}
[Fact] [Fact]
public void Can_Set_DataContext_In_DataTemplate() public void Can_Set_DataContext_In_DataTemplate()
{ {

7
tests/Avalonia.Styling.UnitTests/StyledElementTests.cs

@ -273,13 +273,10 @@ namespace Avalonia.Styling.UnitTests
var root = new TestRoot(); var root = new TestRoot();
var child = new Border(); var child = new Border();
((ISupportInitialize)child).BeginInit(); child.BeginInit();
root.Child = child; root.Child = child;
child.Name = "foo"; child.Name = "foo";
Assert.Null(root.FindControl<Border>("foo")); child.EndInit();
((ISupportInitialize)child).EndInit();
Assert.Same(root.FindControl<Border>("foo"), child);
} }
} }

23
tests/Avalonia.Styling.UnitTests/StyledElementTests_NameScope.cs

@ -1,11 +1,6 @@
// Copyright (c) The Avalonia Project. All rights reserved. // Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Rendering;
using Avalonia.Styling;
using Avalonia.UnitTests; using Avalonia.UnitTests;
using Xunit; using Xunit;
@ -70,23 +65,5 @@ namespace Avalonia.Controls.UnitTests
Assert.Null(NameScope.GetNameScope((StyledElement)root.Presenter).Find("foo")); Assert.Null(NameScope.GetNameScope((StyledElement)root.Presenter).Find("foo"));
} }
[Fact]
public void Control_That_Is_NameScope_Should_Register_With_Parent_NameScope()
{
UserControl userControl;
var root = new TestTemplatedRoot
{
Content = userControl = new UserControl
{
Name = "foo",
}
};
root.ApplyTemplate();
Assert.Same(userControl, root.FindControl<UserControl>("foo"));
Assert.Same(userControl, userControl.FindControl<UserControl>("foo"));
}
} }
} }

Loading…
Cancel
Save