13 changed files with 176 additions and 57 deletions
@ -0,0 +1,32 @@ |
|||
using System; |
|||
|
|||
namespace Avalonia.Controls |
|||
{ |
|||
/// <summary>
|
|||
/// Represents an object that can be queried for resources.
|
|||
/// </summary>
|
|||
public interface IResourceProvider |
|||
{ |
|||
/// <summary>
|
|||
/// Raised when resources in the provider are changed.
|
|||
/// </summary>
|
|||
event EventHandler<ResourcesChangedEventArgs> ResourcesChanged; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether the element has resources.
|
|||
/// </summary>
|
|||
bool HasResources { get; } |
|||
|
|||
/// <summary>
|
|||
/// Tries to find a resource within the provider.
|
|||
/// </summary>
|
|||
/// <param name="key">The resource key.</param>
|
|||
/// <param name="value">
|
|||
/// When this method returns, contains the value associated with the specified key,
|
|||
/// if the key is found; otherwise, null
|
|||
/// <returns>
|
|||
/// True if the resource if found, otherwise false.
|
|||
/// </returns>
|
|||
bool TryGetResource(string key, out object value); |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using Avalonia.Controls; |
|||
using Portable.Xaml.ComponentModel; |
|||
using Portable.Xaml.Markup; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Loads a resource dictionary from a specified URL.
|
|||
/// </summary>
|
|||
public class ResourceInclude : MarkupExtension, IResourceProvider |
|||
{ |
|||
private Uri _baseUri; |
|||
private IResourceDictionary _loaded; |
|||
|
|||
public event EventHandler<ResourcesChangedEventArgs> ResourcesChanged; |
|||
|
|||
/// <summary>
|
|||
/// Gets the loaded resource dictionary.
|
|||
/// </summary>
|
|||
public IResourceDictionary Loaded |
|||
{ |
|||
get |
|||
{ |
|||
if (_loaded == null) |
|||
{ |
|||
var loader = new AvaloniaXamlLoader(); |
|||
_loaded = (IResourceDictionary)loader.Load(Source, _baseUri); |
|||
|
|||
if (_loaded.HasResources) |
|||
{ |
|||
ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs()); |
|||
} |
|||
} |
|||
|
|||
return _loaded; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the source URL.
|
|||
/// </summary>
|
|||
public Uri Source { get; set; } |
|||
|
|||
/// <inhertidoc/>
|
|||
bool IResourceProvider.HasResources => Loaded.HasResources; |
|||
|
|||
/// <inhertidoc/>
|
|||
bool IResourceProvider.TryGetResource(string key, out object value) |
|||
{ |
|||
return Loaded.TryGetResource(key, out value); |
|||
} |
|||
|
|||
/// <inhertidoc/>
|
|||
public override object ProvideValue(IServiceProvider serviceProvider) |
|||
{ |
|||
var tdc = (ITypeDescriptorContext)serviceProvider; |
|||
_baseUri = tdc?.GetBaseUri(); |
|||
return this; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using System; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Media; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Markup.Xaml.UnitTests.Data |
|||
{ |
|||
public class ResourceIncludeTests |
|||
{ |
|||
public class StaticResourceExtensionTests |
|||
{ |
|||
[Fact] |
|||
public void ResourceInclude_Loads_ResourceDictionary() |
|||
{ |
|||
var includeXaml = @"
|
|||
<ResourceDictionary xmlns='https://github.com/avaloniaui'
|
|||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
|
|||
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush> |
|||
</ResourceDictionary> |
|||
";
|
|||
using (StartWithResources(("test:include.xaml", includeXaml))) |
|||
{ |
|||
var xaml = @"
|
|||
<UserControl xmlns='https://github.com/avaloniaui'
|
|||
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
|
|||
<UserControl.Resources> |
|||
<ResourceDictionary> |
|||
<ResourceDictionary.MergedDictionaries> |
|||
<ResourceInclude Source='test:include.xaml'/> |
|||
</ResourceDictionary.MergedDictionaries> |
|||
</ResourceDictionary> |
|||
</UserControl.Resources> |
|||
|
|||
<Border Name='border' Background='{StaticResource brush}'/> |
|||
</UserControl>";
|
|||
|
|||
var loader = new AvaloniaXamlLoader(); |
|||
var userControl = (UserControl)loader.Load(xaml); |
|||
var border = userControl.FindControl<Border>("border"); |
|||
|
|||
var brush = (SolidColorBrush)border.Background; |
|||
Assert.Equal(0xff506070, brush.Color.ToUint32()); |
|||
} |
|||
} |
|||
|
|||
private IDisposable StartWithResources(params (string, string)[] assets) |
|||
{ |
|||
var assetLoader = new MockAssetLoader(assets); |
|||
var services = new TestServices(assetLoader: assetLoader); |
|||
return UnitTestApplication.Start(services); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue