-
I'm a little disappointed with the way resource lookup works in Avalonia (#6021) so have written an extension that will look up resources closer to how it worked in WPF/WinUI (where it searches the entire tree rather than just the current dictionary). I've copied this extension below for others and to explain my problem. The first part of it works fine for all my resources. These are defined in various files and included at the application-level. However, FluentAvalonia resources are not picked up here. I had to add a special case just to lookup resources in the FluentAvaloniaTheme instance. This doesn't seem correct, is it? I would normally expect FluentAvalonia to register resources at the application-level so I don't need to have special code like this. Moreover, this is only a problem in code-behind. Using FluentAvalonia resources in XAML works just fine as-is (as to be expected). Edit: To clarify, I understand why I have to lookup resources specially in FluentAvalonia:
/// <summary>
/// Gets the first resource matching the given key within the application resources dictionary.
/// </summary>
/// <typeparam name="T">The type of resource to return.</typeparam>
/// <param name="app">The application instance.</param>
/// <param name="key">The resource key.</param>
/// <returns>The located resource or default(T).</returns>
public static T GetResource<T>(
this Application app,
object key)
{
if (app.Resources.TryGetResource(key, app.ActualThemeVariant, out object resource))
{
if (resource is T)
{
return (T)resource;
}
}
if (app.Styles.Count > 1 &&
app.Styles[0] is FluentAvaloniaTheme fluentTheme)
{
if (fluentTheme.TryGetResource(key, app.ActualThemeVariant, out resource))
{
if (resource is T)
{
return (T)resource;
}
}
}
#if DEBUG
throw new Exception("Missing resource: " + key?.ToString());
#endif
return default(T);
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
We have two "universal" resource look up methods, implemented as extension methods: Both of these will walk the tree up from the control to the App. FindResource will return Unlike WPF/UWP, we have two places resources can be defined, foreach(var item in App.Current.Styles)
{
if (item.TryGetResource(key, App.Current.ActualThemeVariant, out var value))
{
return value;
}
}
FATheme has to be added to the Application's Styles instead of the ResourceDictionary. It also makes sense this way, given how Avalonia's styling system works. One, there are some things not implemented with ControlThemes that would be incompatible in a ResourceDictionary (not just from upstream, there's some special stuff for CommandBar, I think, I had to implement via |
Beta Was this translation helpful? Give feedback.
We have two "universal" resource look up methods, implemented as extension methods:
void IResourceHost.FindResource(ThemeVariant variant, object key)
bool IResourceHost.TryFindResource(object key, ThemeVariant variant, out object value)
Both of these will walk the tree up from the control to the App. FindResource will return
UnsetValue
if the resource isn't found and TryFindResource returns a bool to determine lookup success.Unlike WPF/UWP, we have two places resources can be defined,
Styles
andResources
. When doing a lookup, you have to remember to search both, Resources first, then Styles. So instead of special casing FATheme, just loop over the Styles collection in App and call TryGe…