Browse Source

Add :empty pseudoclass for ContentControl (#21829)

* Add :empty pseudoclass for ContentControl

* Update ToolTip tests for ContentControl :empty pseudoclass

* Update XAML class tests for ContentControl :empty pseudoclass
pull/21852/head
yoyo 2 months ago
committed by GitHub
parent
commit
7874bd6eff
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 19
      src/Avalonia.Controls/ContentControl.cs
  2. 14
      tests/Avalonia.Controls.UnitTests/ContentControlTests.cs
  3. 6
      tests/Avalonia.Controls.UnitTests/ToolTipTests.cs
  4. 16
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

19
src/Avalonia.Controls/ContentControl.cs

@ -8,8 +8,6 @@ using Avalonia.Data;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.Styling;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
@ -17,8 +15,11 @@ namespace Avalonia.Controls
/// Displays <see cref="Content"/> according to an <see cref="IDataTemplate"/>. /// Displays <see cref="Content"/> according to an <see cref="IDataTemplate"/>.
/// </summary> /// </summary>
[TemplatePart("PART_ContentPresenter", typeof(ContentPresenter))] [TemplatePart("PART_ContentPresenter", typeof(ContentPresenter))]
[PseudoClasses(pcEmpty)]
public class ContentControl : TemplatedControl, IContentControl, IContentPresenterHost public class ContentControl : TemplatedControl, IContentControl, IContentPresenterHost
{ {
private const string pcEmpty = ":empty";
/// <summary> /// <summary>
/// Defines the <see cref="Content"/> property. /// Defines the <see cref="Content"/> property.
/// </summary> /// </summary>
@ -61,6 +62,11 @@ namespace Avalonia.Controls
}.RegisterInNameScope(ns))); }.RegisterInNameScope(ns)));
} }
public ContentControl()
{
UpdatePseudoClasses();
}
/// <summary> /// <summary>
/// Gets or sets the content to display. /// Gets or sets the content to display.
/// </summary> /// </summary>
@ -116,7 +122,7 @@ namespace Avalonia.Controls
{ {
return RegisterContentPresenter(presenter); return RegisterContentPresenter(presenter);
} }
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{ {
base.OnPropertyChanged(change); base.OnPropertyChanged(change);
@ -153,6 +159,13 @@ namespace Avalonia.Controls
{ {
LogicalChildren.Add(newChild); LogicalChildren.Add(newChild);
} }
UpdatePseudoClasses();
}
private void UpdatePseudoClasses()
{
PseudoClasses.Set(pcEmpty, Content is null);
} }
internal override void BuildDebugDisplay(StringBuilder builder, bool includeContent) internal override void BuildDebugDisplay(StringBuilder builder, bool includeContent)

14
tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

@ -17,6 +17,20 @@ namespace Avalonia.Controls.UnitTests
{ {
public class ContentControlTests : ScopedTestBase public class ContentControlTests : ScopedTestBase
{ {
[Fact]
public void Empty_PseudoClass_Should_Track_Content()
{
var target = new ContentControl();
Assert.Contains(":empty", target.Classes);
target.Content = "Content";
Assert.DoesNotContain(":empty", target.Classes);
target.Content = null;
Assert.Contains(":empty", target.Classes);
}
[Fact] [Fact]
public void Template_Should_Be_Instantiated() public void Template_Should_Be_Instantiated()
{ {

6
tests/Avalonia.Controls.UnitTests/ToolTipTests.cs

@ -215,7 +215,7 @@ namespace Avalonia.Controls.UnitTests
window.ApplyTemplate(); window.ApplyTemplate();
window.Presenter!.ApplyTemplate(); window.Presenter!.ApplyTemplate();
Assert.Empty(toolTip.Classes); Assert.DoesNotContain(":open", toolTip.Classes);
} }
} }
@ -240,7 +240,7 @@ namespace Avalonia.Controls.UnitTests
ToolTip.SetIsOpen(decorator, true); ToolTip.SetIsOpen(decorator, true);
Assert.Equal(new[] { ":open" }, toolTip.Classes); Assert.Contains(":open", toolTip.Classes);
VerifyToolTipType(decorator); VerifyToolTipType(decorator);
} }
} }
@ -271,7 +271,7 @@ namespace Avalonia.Controls.UnitTests
AssertToolTipOpen(decorator); AssertToolTipOpen(decorator);
ToolTip.SetIsOpen(decorator, false); ToolTip.SetIsOpen(decorator, false);
Assert.Empty(toolTip.Classes); Assert.DoesNotContain(":open", toolTip.Classes);
} }
} }

16
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

@ -113,7 +113,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.Equal("Foo", ToolTip.GetTip(target)); Assert.Equal("Foo", ToolTip.GetTip(target));
} }
[Fact] [Fact]
public void NonExistent_Property_Throws() public void NonExistent_Property_Throws()
{ {
@ -279,7 +279,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.Equal(expected3, grid.RowDefinitions[2].Height); Assert.Equal(expected3, grid.RowDefinitions[2].Height);
Assert.Equal(expected4, grid.RowDefinitions[3].Height); Assert.Equal(expected4, grid.RowDefinitions[3].Height);
} }
[Fact] [Fact]
public void Grid_Row_Col_Definitions_Are_Parsed_Space_Delimiter() public void Grid_Row_Col_Definitions_Are_Parsed_Space_Delimiter()
{ {
@ -905,7 +905,8 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
var xaml = "<Button xmlns='https://github.com/avaloniaui' Classes='foo bar'/>"; var xaml = "<Button xmlns='https://github.com/avaloniaui' Classes='foo bar'/>";
var target = (Button)AvaloniaRuntimeXamlLoader.Load(xaml); var target = (Button)AvaloniaRuntimeXamlLoader.Load(xaml);
Assert.Equal(new[] { "foo", "bar" }, target.Classes); Assert.Contains("foo", target.Classes);
Assert.Contains("bar", target.Classes);
} }
[Fact] [Fact]
@ -921,7 +922,8 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
</Button>"; </Button>";
var target = (Button)AvaloniaRuntimeXamlLoader.Load(xaml); var target = (Button)AvaloniaRuntimeXamlLoader.Load(xaml);
Assert.Equal(new[] { "foo", "bar" }, target.Classes); Assert.Contains("foo", target.Classes);
Assert.Contains("bar", target.Classes);
} }
[Fact] [Fact]
@ -970,16 +972,16 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Child = child; Child = child;
} }
} }
public class ObjectWithoutPublicCtor public class ObjectWithoutPublicCtor
{ {
public ObjectWithoutPublicCtor(string param) public ObjectWithoutPublicCtor(string param)
{ {
Test1 = param; Test1 = param;
} }
public string? Test1 { get; set; } public string? Test1 { get; set; }
public string? Test2 { get; set; } public string? Test2 { get; set; }
} }

Loading…
Cancel
Save