考えられる解決策の 1 つは、ヘルパー クラスを追加し、そのクラスのインスタンスをコンバーター パラメーターとして渡すことです。インスタンスは、手動で XAML で初期化する必要があります。インスタンスは、モデル インスタンスのプロパティの属性の値を取得するために必要なすべてのデータで構成されます。ソリューションは一般化されており、コンバーター ロジック内にハードコーディングされたデータはありません。コンバーターの「値」パラメーターも必要ありません。
したがって、結果は次のようになります。
ビューモデルと同じアセンブリ内の何か。コンバーターとヘルパー クラス (簡素化 - null チェックなどなし):
namespace MyProject.Converters
{
public class MetadataParameters
{
public Type ModelType { get; set; }
public string ModelProperty { get; set; }
public Type AttributeType { get; set; }
public string AttributeProperty { get; set; }
}
public class MetadataConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var mp = parameter as MetadataParameters;
var modelPropertyInfo = mp.ModelType.GetProperty(mp.ModelProperty);
var attribute = modelPropertyInfo
.GetCustomAttributes(true)
.Cast<Attribute>()
.FirstOrDefault(memberInfo => memberInfo.GetType() == mp.AttributeType);
var attributeProperty = attribute.GetType().GetProperty(mp.AttributeProperty);
return attributeProperty.GetValue(attribute, null);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
リソース ファイル (XAML):
xmlns:converters="clr-namespace:MyProject.Converters"
...
<converters:MetadataConverter x:Key="metadataConverter" />
ビュー ファイル内:
<!-- language: lang-xml -->
xmlns:converters="clr-namespace:MyProject.Converters"
xmlns:DataAnnotations="clr-namespace:System.ComponentModel.DataAnnotations;assembly=System.ComponentModel.DataAnnotations"
xmlns:Models="clr-namespace:MyProject.Models"
...
<TextBlock
<TextBlock.Text>
<Binding
Mode="OneWay"
Converter="{StaticResource metadataConverter}">
<Binding.ConverterParameter>
<converters:MetadataParameters
ModelType="{x:Type Models:Model}"
ModelProperty="ModelProperty"
AttributeType="{x:Type DataAnnotations:DisplayAttribute}"
AttributeProperty="Name" />
</Binding.ConverterParameter>
</Binding>
</TextBlock.Text>
</TextBlock>