Browse Source

Detect resources added in new styles.

pull/1136/head
Steven Kirk 9 years ago
parent
commit
2a61bbcb64
  1. 3
      src/Avalonia.Controls/Application.cs
  2. 3
      src/Avalonia.Controls/Control.cs
  3. 5
      src/Avalonia.Styling/Controls/IResourceProvider.cs
  4. 3
      src/Avalonia.Styling/Styling/Style.cs
  5. 23
      src/Avalonia.Styling/Styling/Styles.cs
  6. 3
      src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs
  7. 109
      tests/Avalonia.Controls.UnitTests/ControlTests_Resources.cs

3
src/Avalonia.Controls/Application.cs

@ -125,6 +125,9 @@ namespace Avalonia
/// </summary>
IStyleHost IStyleHost.StylingParent => null;
/// <inheritdoc/>
bool IResourceProvider.HasResources => _resources?.Count > 0;
/// <summary>
/// Initializes the application by loading XAML etc.
/// </summary>

3
src/Avalonia.Controls/Control.cs

@ -382,6 +382,9 @@ namespace Avalonia.Controls
/// </summary>
IAvaloniaReadOnlyList<ILogical> ILogical.LogicalChildren => LogicalChildren;
/// <inheritdoc/>
bool IResourceProvider.HasResources => _resources?.Count > 0 || Styles.HasResources;
/// <inheritdoc/>
IAvaloniaReadOnlyList<string> IStyleable.Classes => Classes;

5
src/Avalonia.Styling/Controls/IResourceProvider.cs

@ -12,6 +12,11 @@ namespace Avalonia.Controls
/// </summary>
event EventHandler<ResourcesChangedEventArgs> ResourcesChanged;
/// <summary>
/// Gets a value indicating whether the provider has resources.
/// </summary>
bool HasResources { get; }
/// <summary>
/// Tries to find a resource within the element.
/// </summary>

3
src/Avalonia.Styling/Styling/Style.cs

@ -66,6 +66,9 @@ namespace Avalonia.Styling
[Content]
public IList<ISetter> Setters { get; set; } = new List<ISetter>();
/// <inheritdoc/>
bool IResourceProvider.HasResources => _resources?.Count > 0;
/// <summary>
/// Attaches the style to a control if the style's selector matches.
/// </summary>

23
src/Avalonia.Styling/Styling/Styles.cs

@ -20,14 +20,33 @@ namespace Avalonia.Styling
{
ResetBehavior = ResetBehavior.Remove;
this.ForEachItem(
x => x.ResourcesChanged += SubResourceChanged,
x => x.ResourcesChanged -= SubResourceChanged,
x =>
{
if (x.HasResources)
{
ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
}
x.ResourcesChanged += SubResourceChanged;
},
x =>
{
if (x.HasResources)
{
ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
}
x.ResourcesChanged -= SubResourceChanged;
},
() => { });
}
/// <inheritdoc/>
public event EventHandler<ResourcesChangedEventArgs> ResourcesChanged;
/// <inheritdoc/>
public bool HasResources => _resources?.Count > 0 || this.Any(x => x.HasResources);
/// <summary>
/// Gets or sets a dictionary of style resources.
/// </summary>

3
src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs

@ -50,6 +50,9 @@ namespace Avalonia.Markup.Xaml.Styling
}
}
/// <inheritdoc/>
bool IResourceProvider.HasResources => Loaded.HasResources;
/// <inheritdoc/>
public void Attach(IStyleable control, IStyleHost container)
{

109
tests/Avalonia.Controls.UnitTests/ControlTests_Resources.cs

@ -2,6 +2,8 @@
// 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.Styling;
using Avalonia.UnitTests;
using Xunit;
@ -142,5 +144,112 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal("foo-value", target.FindResource("foo"));
}
[Fact]
public void Adding_Resource_Should_Call_Raise_ResourceChanged_On_Logical_Children()
{
Border child;
var target = new ContentControl
{
Content = child = new Border(),
Template = ContentControlTemplate(),
};
var raisedOnTarget = false;
var raisedOnPresenter = false;
var raisedOnChild = false;
target.Measure(Size.Infinity);
target.ResourcesChanged += (_, __) => raisedOnTarget = true;
target.Presenter.ResourcesChanged += (_, __) => raisedOnPresenter = true;
child.ResourcesChanged += (_, __) => raisedOnChild = true;
target.Resources.Add("foo", "bar");
Assert.True(raisedOnTarget);
Assert.False(raisedOnPresenter);
Assert.True(raisedOnChild);
}
[Fact]
public void Adding_Resource_To_Styles_Should_Raise_ResourceChanged()
{
var target = new Decorator();
var raised = false;
target.ResourcesChanged += (_, __) => raised = true;
target.Styles.Resources.Add("foo", "bar");
Assert.True(raised);
}
[Fact]
public void Adding_Resource_To_Nested_Style_Should_Raise_ResourceChanged()
{
Style style;
var target = new Decorator
{
Styles =
{
(style = new Style()),
}
};
var raised = false;
target.ResourcesChanged += (_, __) => raised = true;
style.Resources.Add("foo", "bar");
Assert.True(raised);
}
[Fact]
public void Adding_Style_With_Resource_Should_Raise_ResourceChanged()
{
Style style = new Style
{
Resources = { { "foo", "bar" } },
};
var target = new Decorator();
var raised = false;
target.ResourcesChanged += (_, __) => raised = true;
target.Styles.Add(style);
Assert.True(raised);
}
[Fact]
public void Removing_Style_With_Resource_Should_Raise_ResourceChanged()
{
var target = new Decorator
{
Styles =
{
new Style
{
Resources = { { "foo", "bar" } },
}
}
};
var raised = false;
target.ResourcesChanged += (_, __) => raised = true;
target.Styles.Clear();
Assert.True(raised);
}
private IControlTemplate ContentControlTemplate()
{
return new FuncControlTemplate<ContentControl>(x =>
new ContentPresenter
{
Name = "PART_ContentPresenter",
[!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
});
}
}
}

Loading…
Cancel
Save