Browse Source

Move Theme to StyledElement.

The WPF equivalent (`Style`) is in `FrameworkElement` so it would make sense. Will also make stuff a lot easier and removes the need for an `IThemed` interface.
pull/8262/head
Steven Kirk 4 years ago
parent
commit
fc3c036b02
  1. 25
      src/Avalonia.Base/StyledElement.cs
  2. 7
      src/Avalonia.Base/Styling/IStyleable.cs
  3. 13
      src/Avalonia.Base/Styling/IThemed.cs
  4. 23
      src/Avalonia.Base/Styling/Styler.cs
  5. 25
      src/Avalonia.Controls/Primitives/TemplatedControl.cs
  6. 5
      tests/Avalonia.Markup.Xaml.UnitTests/Converters/AvaloniaPropertyConverterTest.cs

25
src/Avalonia.Base/StyledElement.cs

@ -12,8 +12,6 @@ using Avalonia.Logging;
using Avalonia.LogicalTree;
using Avalonia.Styling;
#nullable enable
namespace Avalonia
{
/// <summary>
@ -55,6 +53,12 @@ namespace Avalonia
nameof(TemplatedParent),
o => o.TemplatedParent,
(o ,v) => o.TemplatedParent = v);
/// <summary>
/// Defines the <see cref="Theme"/> property.
/// </summary>
public static readonly StyledProperty<ControlTheme?> ThemeProperty =
AvaloniaProperty.Register<StyledElement, ControlTheme?>(nameof(Theme));
private int _initCount;
private string? _name;
@ -230,6 +234,15 @@ namespace Avalonia
internal set => SetAndRaise(TemplatedParentProperty, ref _templatedParent, value);
}
/// <summary>
/// Gets or sets the theme to be applied to the element.
/// </summary>
public ControlTheme? Theme
{
get { return GetValue(ThemeProperty); }
set { SetValue(ThemeProperty, value); }
}
/// <summary>
/// Gets the styled element's logical children.
/// </summary>
@ -590,6 +603,14 @@ namespace Avalonia
{
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == ThemeProperty)
InvalidateStyles();
}
private static void DataContextNotifying(IAvaloniaObject o, bool updateStarted)
{
if (o is StyledElement element)

7
src/Avalonia.Base/Styling/IStyleable.cs

@ -3,8 +3,6 @@ using System.Collections.Generic;
using Avalonia.Collections;
using Avalonia.Metadata;
#nullable enable
namespace Avalonia.Styling
{
/// <summary>
@ -28,6 +26,11 @@ namespace Avalonia.Styling
/// </summary>
ITemplatedControl? TemplatedParent { get; }
/// <summary>
/// Gets the theme to be applied to the control.
/// </summary>
public ControlTheme? Theme { get; }
/// <summary>
/// Notifies the element that a style has been applied.
/// </summary>

13
src/Avalonia.Base/Styling/IThemed.cs

@ -1,13 +0,0 @@
namespace Avalonia.Styling
{
/// <summary>
/// Represents a themed element.
/// </summary>
public interface IThemed
{
/// <summary>
/// Gets the theme style for the element.
/// </summary>
public ControlTheme? Theme { get; }
}
}

23
src/Avalonia.Base/Styling/Styler.cs

@ -1,33 +1,24 @@
using System;
#nullable enable
namespace Avalonia.Styling
{
public class Styler : IStyler
{
public void ApplyStyles(IStyleable target)
{
target = target ?? throw new ArgumentNullException(nameof(target));
_ = target ?? throw new ArgumentNullException(nameof(target));
// If the control has a themed templated parent then first apply the styles from
// the templated parent theme.
if (target.TemplatedParent is IThemed themedTemplatedParent)
{
themedTemplatedParent.Theme?.TryAttach(target, themedTemplatedParent);
}
if (target.TemplatedParent is IStyleable styleableParent)
styleableParent.Theme?.TryAttach(target, styleableParent);
// If the control itself is themed, then next apply the control theme.
if (target is IThemed themed)
{
themed.Theme?.TryAttach(target, target);
}
// Next apply the control theme.
target.Theme?.TryAttach(target, target);
// Apply styles from the rest of the tree.
if (target is IStyleHost styleHost)
{
ApplyStyles(target, styleHost);
}
}
private void ApplyStyles(IStyleable target, IStyleHost host)
@ -35,14 +26,10 @@ namespace Avalonia.Styling
var parent = host.StylingParent;
if (parent != null)
{
ApplyStyles(target, parent);
}
if (host.IsStylesInitialized)
{
host.Styles.TryAttach(target, host);
}
}
}
}

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

@ -12,7 +12,7 @@ namespace Avalonia.Controls.Primitives
/// <summary>
/// A lookless control whose visual appearance is defined by its <see cref="Template"/>.
/// </summary>
public class TemplatedControl : Control, IThemed, ITemplatedControl
public class TemplatedControl : Control, ITemplatedControl
{
/// <summary>
/// Defines the <see cref="Background"/> property.
@ -86,12 +86,6 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<IControlTemplate?> TemplateProperty =
AvaloniaProperty.Register<TemplatedControl, IControlTemplate?>(nameof(Template));
/// <summary>
/// Defines the <see cref="Theme"/> property.
/// </summary>
public static readonly StyledProperty<ControlTheme?> ThemeProperty =
AvaloniaProperty.Register<TemplatedControl, ControlTheme?>(nameof(Theme));
/// <summary>
/// Defines the IsTemplateFocusTarget attached property.
/// </summary>
@ -234,15 +228,6 @@ namespace Avalonia.Controls.Primitives
set { SetValue(TemplateProperty, value); }
}
/// <summary>
/// Gets or sets the theme to be applied to the control.
/// </summary>
public ControlTheme? Theme
{
get { return GetValue(ThemeProperty); }
set { SetValue(ThemeProperty, value); }
}
/// <summary>
/// Gets the value of the IsTemplateFocusTargetProperty attached property on a control.
/// </summary>
@ -380,14 +365,6 @@ namespace Avalonia.Controls.Primitives
{
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == ThemeProperty)
InvalidateStyles();
}
/// <summary>
/// Called when the control's template is applied.
/// </summary>

5
tests/Avalonia.Markup.Xaml.UnitTests/Converters/AvaloniaPropertyConverterTest.cs

@ -137,6 +137,11 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters
get { throw new NotImplementedException(); }
}
public ControlTheme Theme
{
get { throw new NotImplementedException(); }
}
public void DetachStyles()
{
throw new NotImplementedException();

Loading…
Cancel
Save