A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

101 lines
2.9 KiB

using Avalonia.Styling;
using System;
using Avalonia.Controls;
using System.Collections.Generic;
#nullable enable
namespace Avalonia.Markup.Xaml.Styling
{
/// <summary>
/// Includes a style from a URL.
/// </summary>
public class StyleInclude : IStyle, IResourceProvider
{
private readonly Uri _baseUri;
private IStyle[]? _loaded;
private bool _isLoading;
/// <summary>
/// Initializes a new instance of the <see cref="StyleInclude"/> class.
/// </summary>
/// <param name="baseUri">The base URL for the XAML context.</param>
public StyleInclude(Uri baseUri)
{
_baseUri = baseUri;
}
/// <summary>
/// Initializes a new instance of the <see cref="StyleInclude"/> class.
/// </summary>
/// <param name="serviceProvider">The XAML service provider.</param>
public StyleInclude(IServiceProvider serviceProvider)
{
_baseUri = serviceProvider.GetContextBaseUri();
}
public IResourceHost? Owner => (Loaded as IResourceProvider)?.Owner;
/// <summary>
/// Gets or sets the source URL.
/// </summary>
public Uri? Source { get; set; }
/// <summary>
/// Gets the loaded style.
/// </summary>
public IStyle Loaded
{
get
{
if (_loaded == null)
{
_isLoading = true;
var loaded = (IStyle)AvaloniaXamlLoader.Load(Source, _baseUri);
_loaded = new[] { loaded };
_isLoading = false;
}
return _loaded?[0]!;
}
}
bool IResourceNode.HasResources => (Loaded as IResourceProvider)?.HasResources ?? false;
IReadOnlyList<IStyle> IStyle.Children => _loaded ?? Array.Empty<IStyle>();
public event EventHandler OwnerChanged
{
add
{
if (Loaded is IResourceProvider rp)
{
rp.OwnerChanged += value;
}
}
remove
{
if (Loaded is IResourceProvider rp)
{
rp.OwnerChanged -= value;
}
}
}
public SelectorMatchResult TryAttach(IStyleable target, IStyleHost? host) => Loaded.TryAttach(target, host);
public bool TryGetResource(object key, out object? value)
{
if (!_isLoading && Loaded is IResourceProvider p)
{
return p.TryGetResource(key, out value);
}
value = null;
return false;
}
void IResourceProvider.AddOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.AddOwner(owner);
void IResourceProvider.RemoveOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.RemoveOwner(owner);
}
}