Skip to content

Commit

Permalink
feat(xamlreader): Support CustomResource
Browse files Browse the repository at this point in the history
  • Loading branch information
seanocali committed Sep 8, 2022
1 parent cd246d6 commit c9d011c
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/Uno.UI.Tests/Uno.UI.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
<Page Include="HotReload\Windows_UI_Xaml\**\*.xaml" />
<Page Include="App\**\*.xaml" />
<None Remove="Lottie\animation.json" />
<None Remove="Windows_UI_Xaml_Markup\XamlReaderTests\When_CustomResource.xamltest" />
<Page Include="..\SamplesApp\UITests.Shared\Windows_UI_Xaml\Resources\Test_Dictionary_Linked.xaml" Link="App/Linked/Test_Dictionary_Linked.xaml" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,43 @@ public void When_ThemeResource_Lazy()
Assert.AreEqual(44.0, panel.Height);
}

[TestMethod]
public void When_CustomResource()
{
var savedState = Windows.UI.Xaml.Resources.CustomXamlResourceLoader.Current;
try
{
var loader = new TestCustomXamlResourceLoader();
var resourceValue = "This is a CustomResource.";
var resourceKey = "myCustomResource";
loader.TestCustomResources[resourceKey] = resourceValue;
Windows.UI.Xaml.Resources.CustomXamlResourceLoader.Current = loader;

var s = GetContent(nameof(When_CustomResource));
var r = Windows.UI.Xaml.Markup.XamlReader.Load(s) as Page;

Assert.IsNotNull(r);

var tb = r.Content as TextBlock;

Assert.IsNotNull(tb);
Assert.AreEqual(resourceValue, tb.Text);

var objectType = tb.GetType().FullName;
var propertyName = nameof(tb.Text);
var propertyType = tb.Text.GetType().FullName;

Assert.AreEqual(loader.LastResourceId, resourceKey);
Assert.AreEqual(loader.LastObjectType, objectType);
Assert.AreEqual(loader.LastPropertyName, propertyName);
Assert.AreEqual(loader.LastPropertyType, propertyType);
}
finally
{
Windows.UI.Xaml.Resources.CustomXamlResourceLoader.Current = savedState;
}
}

[TestMethod]
public void When_TextBlock_Basic()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Resources;

namespace Uno.UI.Tests.Windows_UI_Xaml_Markup.XamlReaderTests
{
internal class TestCustomXamlResourceLoader : CustomXamlResourceLoader
{
internal Dictionary<string, object> TestCustomResources { get; set; } = new Dictionary<string, object>();

public string LastResourceId { get; set; }
public string LastObjectType { get; set; }
public string LastPropertyName { get; set; }
public string LastPropertyType { get; set; }

protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
{
LastResourceId = resourceId;
LastObjectType = objectType;
LastPropertyName = propertyName;
LastPropertyType = propertyType;
if (TestCustomResources.ContainsKey(resourceId) && TestCustomResources[resourceId].GetType().FullName == propertyType)
{
return TestCustomResources[resourceId];
}
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Name="rootPage"
mc:Ignorable="d">

<TextBlock Text="{CustomResource myCustomResource}" />
</Page>
44 changes: 32 additions & 12 deletions src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Windows.UI.Text;
using Windows.Foundation.Metadata;
using Color = Windows.UI.Color;
using Windows.UI.Xaml.Resources;

#if XAMARIN_ANDROID
using _View = Android.Views.View;
Expand Down Expand Up @@ -711,7 +712,7 @@ private void ProcessMemberMarkupExtension(object instance, object? rootInstance,
{
ProcessBindingMarkupNode(instance, rootInstance, member);
}
else if (IsStaticResourceMarkupNode(member) || IsThemeResourceMarkupNode(member))
else if (IsStaticResourceMarkupNode(member) || IsThemeResourceMarkupNode(member) || IsCustomResourceMarkupNode(member))
{
ProcessStaticResourceMarkupNode(instance, member, propertyInfo);
}
Expand All @@ -730,20 +731,35 @@ private void ProcessStaticResourceMarkupNode(object instance, XamlMemberDefiniti
&& dependencyProperty != null
&& instance is DependencyObject dependencyObject)
{
ResourceResolver.ApplyResource(
dependencyObject,
dependencyProperty,
keyName,
isThemeResourceExtension: IsThemeResourceMarkupNode(member),
isHotReloadSupported: true);

if (instance is FrameworkElement fe)
if (IsCustomResourceMarkupNode(member))
{
fe.Loading += delegate
var objectType = dependencyObject.GetType().FullName;
var propertyName = dependencyProperty.Name;
var propertyType = dependencyProperty.Type.FullName;
var resource = CustomXamlResourceLoader.Current?.GetResourceInternal(keyName, objectType, propertyName, propertyType);
if (resource != null && resource.GetType() == dependencyProperty.Type)
{
fe.UpdateResourceBindings();
};
dependencyObject.SetValue(dependencyProperty, resource);
}
}
else
{
ResourceResolver.ApplyResource(
dependencyObject,
dependencyProperty,
keyName,
isThemeResourceExtension: IsThemeResourceMarkupNode(member),
isHotReloadSupported: true);

if (instance is FrameworkElement fe)
{
fe.Loading += delegate
{
fe.UpdateResourceBindings();
};
}
}

}
else if (propertyInfo != null)
{
Expand Down Expand Up @@ -792,6 +808,9 @@ private bool IsStaticResourceMarkupNode(XamlMemberDefinition member)
private bool IsThemeResourceMarkupNode(XamlMemberDefinition member)
=> member.Objects.Any(o => o.Type.Name == "ThemeResource");

private bool IsCustomResourceMarkupNode(XamlMemberDefinition member)
=> member.Objects.Any(o => o.Type.Name == "CustomResource");

private bool IsResourcesProperty(PropertyInfo propertyInfo)
=> propertyInfo.Name == "Resources" && propertyInfo.PropertyType == typeof(ResourceDictionary);

Expand Down Expand Up @@ -996,6 +1015,7 @@ private static bool IsMarkupExtension(XamlMemberDefinition member)
|| m.Type.Name == "Bind"
|| m.Type.Name == "StaticResource"
|| m.Type.Name == "ThemeResource"
|| m.Type.Name == "CustomResource"
|| m.Type.Name == "TemplateBinding"
)
.Any();
Expand Down

0 comments on commit c9d011c

Please sign in to comment.