首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过反射访问主题/Generic.xaml

通过反射访问主题/Generic.xaml
EN

Stack Overflow用户
提问于 2021-12-06 10:18:42
回答 2查看 139关注 0票数 -3

是否有任何方法可以使用反射访问主题/通用ResourceDictionary

我试着在Application.Resources中挖掘,但这似乎是个错误的地方。然后我试着分析了大会的ResourceStream,但也没有成功。

那么,有人知道我如何从程序集中获取上述ResourceDictionary的实例吗?

在有人问“为什么”=>之前,因为我想搞砸它。

这是我得到的最接近的,但它会抛出错误,它的某些部分无法加载,所以我假设它是一个“副本”,而不是使用的?

代码语言:javascript
复制
        System.Uri resourceLocater = new System.Uri("/ASMNAME;component/themes/generic.xaml", System.UriKind.Relative);

        ResourceDictionary dictionary =(ResourceDictionary) Application.LoadComponent(resourceLocater);
EN

回答 2

Stack Overflow用户

发布于 2021-12-06 11:49:59

@CSharpie的提供解决方案很慢,因为它使用反射来调用内部库代码。但是更重要的是,它的实现是非常不安全和非常不稳定的,因为它依赖于任何时候都可以更改的非公共库代码。在生产代码中使用这种实现是不负责任和不专业的。

在引用答案的情况下,不使用反射调用FrameworkElement.FindResource的内部,只需直接调用该方法!

更好地使用公共API:

Generic.xaml

代码语言:javascript
复制
<ResourceDictionary>
  <Style TargetType="{x:Type MyCustomControl}">
    ...
  </Style>
</ResourceDictionary>

下面的代码假设Generic.xaml文件位于名为"Net.Wpf“的程序集中。您可以调用Assembly.GetManifestResourceNames来获取现有资源名称的列表。

在本例中,所需的名称是"Net.Wpf.g.resources“。

然后像这样查找资源:

代码语言:javascript
复制
// Get the assembly that contains the Themes/Generic.xaml file
Assembly themesAssembly = Assembly.GetExecutingAssembly();
await using Stream themesResourceStream = themesAssembly.GetManifestResourceStream("Net.Wpf.g.resources");
using var resourceReader = new System.Resources.ResourceReader(themesResourceStream);
await using var themesBamlStream = resourceReader
  .OfType<DictionaryEntry>()
  .First(entry => entry.Key.Equals("themes/generic.baml"))
  .Value as Stream;
using var themesBamlReader = new System.Windows.Baml2006.Baml2006Reader(themesBamlStream);
var genericXamlResources = System.Windows.Markup.XamlReader.Load(themesBamlReader) as ResourceDictionary;
Style customControlStyle = genericXamlResources[typeof(MyCustomControl)] as Style;

// *******************************
// Same can be achieved by calling
Style customControlStyle = FindResource(typeof(ShortcutButton)) as Style;

注意,XAML资源字典(将构建操作设置为"Page")通常在嵌入到程序集中之前编译为BAML (二进制格式)。因此,在访问资源之前,必须将BAML转换回XAML。

票数 0
EN

Stack Overflow用户

发布于 2021-12-06 10:48:55

我现在让它起作用了

我在这里找到了怎么做的:https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/SystemResources.cs,376

代码语言:javascript
复制
Assembly asm = .....
var systemResourcesType = typeof(Application).Assembly.GetType("System.Windows.SystemResources");
var ensuremethod = systemResourcesType.GetMethod("EnsureDictionarySlot", BindingFlags.NonPublic | BindingFlags.Static);
var loadMethod = ensuremethod.ReturnType.GetMethod("LoadGenericDictionary", BindingFlags.NonPublic | BindingFlags.Instance);

var resourceDictionaries = ensuremethod.Invoke(null, new[] { asm });

var resourceDictionary = (ResourceDictionary)loadMethod.Invoke(resourceDictionaries, new object[]{false});
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70243901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档