我目前正在尝试获取XAML(WPF)中的属性的显示名称,并试图实现this question "Access DisplayName in xaml"的答案。
为了测试这一点,我创建了一个带有属性和DisplayAttribute
的类(我对.resx
文件使用本地化来获取本地化的字符串),
public partial class Employee
{
public Employee()
{
}
private string? firstName;
[Display(Name = nameof(Strings.firstName), ResourceType = typeof(Strings))]
public string? FirstName
{
get => firstName;
set => SetProperty(ref firstName, value, true);
}
修改了另一个问题中的MarkupExtension
以允许null
值,
internal class DisplayNameExtension : MarkupExtension
{
public Type Type { get; set; }
public string PropertyName { get; set; }
public DisplayNameExtension() { }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (Type.GetProperty(PropertyName) is PropertyInfo prop)
{
if (prop.GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault() is DisplayAttribute attribute && !string.IsNullOrEmpty(attribute.Name))
{
return attribute.Name;
}
}
return string.Empty;
}
}
并试图用以下方式来描述:
<TextBlock Text="{local:DisplayName PropertyName=FirstName, Type=model:Employee}"/>
(Employee
是另一个项目的一部分,引用是正确的)
现在,当我停止应用程序并在调用方法时查看prop
属性时,确定了正确的属性,但即使我设置了DisplayAttribute
,这里也不存在任何属性。使用调试器查看内部prop:
我在这里错过了一些显而易见的东西,还是获得属性的解决方案有点复杂?
**编辑:**感谢@EldHasp指出我需要查看CustomAttributes而不是Attributes。现在我看到了我实现的真实的问题:.resx
文件的转换键用作显示名称,而不是转换本身。我认为它的工作原理与RequiredAttribute类似,但事实似乎并非如此:
[Required(ErrorMessageResourceName = nameof(Strings.employeeFirstNameRequired), ErrorMessageResourceType = typeof(Strings))]
2条答案
按热度按时间jdgnovmf1#
ProvideValue
方法的实现将返回密钥。它应该基于该键执行资源查找并返回本地化值。
有一个
ResourceManager
的GetString
方法,你可以使用它:只需将“strings”替换为
.resx
文件和自动生成的类的名称。qxsslcnc2#
我不太明白你的问题。我觉得你找错地方了。您需要查看CustomAttributes集合。
**P.S.**略有改进的实现(不检查错误和异常):