【问题标题】:Any way to set a ResourceDictionary key to match the class name?有什么方法可以设置 ResourceDictionary 键以匹配类名?
【发布时间】:2023-07-20 03:33:02
【问题描述】:

我在 XAML 资源字典中有很多 <conv:[ConverterName] x:Key="[ConverterName]"/> 条目,并且每次键都与类型名称匹配。

有没有办法让密钥自动从类型中获取名称,类似于nameof?除了方便之外,我还希望代码能够更易于重构。

【问题讨论】:

  • 同名但来自不同命名空间的类型是什么? ;)
  • 是的,这可能是个问题。我总是将转换器放在.Converters 命名空间中,所以我避开了那个。

标签: c# wpf xaml resourcedictionary


【解决方案1】:

在 XAML 中无法执行此操作,但您可以使用反射以编程方式执行此操作。像这样的:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        //get all types that implements from all assemlies in the AppDomain
        foreach(var converterType in AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(a => a.GetExportedTypes())
            .Where(t => typeof(IValueConverter).IsAssignableFrom(t) 
                && !t.IsAbstract 
                && !t.IsInterface))
        {
            //...and add them as resources to <Application.Resources>:
            Current.Resources.Add(converterType.Name, Activator.CreateInstance(converterType));
        }
    }
}

【讨论】:

  • 嘿,我已经因为使用太多反射而被告知了!我有点担心这可能是唯一的方法,但这是有道理的。我将在 where 子句中添加一个“并且有一个默认构造函数”。
  • 在尝试了这个之后,我还添加了对typeof(IMultiValueConverter).IsAssignableFrom(t) 的检查,以覆盖(显然)多值的。