Я обнаружил, что вы можете заставить это работать, используя ComponentResourceKey.В своих словарях ресурсов темы определите ресурсы следующим образом:
<!-- themes\aero.normalcolor.xaml -->
<BitmapImage x:Key="{ComponentResourceKey ResourceId=IconSave, TypeInTargetAssembly={x:Type local:CustomControl}}" UriSource="/MyWPFApp;component/Resources/Icons16/Aero/disk.png"/>
<!-- themes\luna.normalcolor.xaml -->
<BitmapImage x:Key="{ComponentResourceKey ResourceId=IconSave, TypeInTargetAssembly={x:Type local:CustomControl}}" UriSource="/MyWPFApp;component/Resources/Icons16/Luna/disk.png"/>
Здесь local:CustomControl
может быть либо основным окном, либо пользовательским элементом управления в вашей сборке.Интересно, однако, что на самом деле это не имеет значения, если это пользовательский, так что он гарантирует, что вы заставите его загрузить эти ресурсы.
Вам также необходимо обновить AssemblyInfo.cs, чтобы убедиться, что ThemeInfoпросматривает исходную сборку для словарей ресурсов темы со следующим
[assembly:ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly )]
Теперь внутри вашего XAML (независимо от того, какой элемент управления вам нравится, необязательно должен быть CustomControl), вы можете написать следующее, чтобы использовать ресурс
<Image Source="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomControl}, ResourceId=IconSave}}"/>
Используя DynamicResource, вы также можете динамически обновлять приложение при изменении темы (вместо StaticResource, который потребует перезапуска).
Я думаю, что, вероятно, можно написать более чистую реализациюComponentResourceKey, чтобы скрыть TypeInTargetAssembly (на которую я дам пример), но по крайней мере это должно заставить вас работать.
Чтобы обновить, я только что реализовал улучшение для ComponentResourceKey, которое рассмотриттекущая сборка и найти первыйUIElement, который можно использовать для TypeInTargetAssembly.
public class ThemeResourceKey : ComponentResourceKey
{
public ThemeResourceKey(String resourceId)
{
ResourceId = resourceId;
var assembly = Assembly.GetExecutingAssembly();
var types = assembly.GetTypes().Where(t => typeof (UIElement).IsAssignableFrom(t));
var uiElementType = types.FirstOrDefault();
if(uiElementType == default(Type))
throw new ArgumentException("No custom UIElements defined within this XAML");
TypeInTargetAssembly = uiElementType;
}
}
Теперь вы можете определить словарь ресурсов с помощью этого
<!-- themes\aero.normalcolor.xaml -->
<BitmapImage x:Key="{local:ThemeResourceKey IconSave}" UriSource="/MyWPFApp;component/Resources/Icons16/Aero/disk.png"/>
и ссылаться на него в своих элементах управления следующим образом
<Image Source="{DynamicResource {local:ThemeResourceKey IconSave}}"/>
Что должно быть намного чище.Надеюсь, что это поможет, и дайте мне знать, если у вас есть какие-либо проблемы с этим.