2011-05-27 9 views
14

¿Cómo puedo acceder al valor de DisplayName en XAML?Acceso DisplayName en xaml

Tengo:

public class ViewModel { 
    [DisplayName("My simple property")] 
    public string Property { 
    get { return "property";} 
    } 
} 

XAML:

<TextBlock Text="{Binding ??Property.DisplayName??}"/> 
<TextBlock Text="{Binding Property}"/> 

¿Hay alguna manera de obligar DisplayName de tal manera o simmilar? La mejor idea será usar este DisplayName como clave para los recursos y presentar algo de los recursos.

Respuesta

20

me gustaría utilizar un markup extension: el uso

public class DisplayNameExtension : MarkupExtension 
{ 
    public Type Type { get; set; } 

    public string PropertyName { get; set; } 

    public DisplayNameExtension() { } 
    public DisplayNameExtension(string propertyName) 
    { 
     PropertyName = propertyName; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     // (This code has zero tolerance) 
     var prop = Type.GetProperty(PropertyName); 
     var attributes = prop.GetCustomAttributes(typeof(DisplayNameAttribute), false); 
     return (attributes[0] as DisplayNameAttribute).DisplayName; 
    } 
} 

Ejemplo:

<TextBlock Text="{m:DisplayName TestInt, Type=local:MainWindow}"/> 
public partial class MainWindow : Window 
{ 
    [DisplayName("Awesome Int")] 
    public int TestInt { get; set; } 
    //... 
} 
+3

También iría con un MarkupExtension pero eso aprovecha un DisplayNameAttribute localizable personalizado como se muestra [aquí] (http://stackoverflow.com/questions/356464/localization-of-displaynameattribute) – CodeNaked

+0

@CodeNaked: Buena idea, mientras yo estaba al tanto de los problemas de localización, no pensé en ningún enfoque particular yo mismo. –

+0

Cualquier idea ¿cómo podemos hacer que funcione si el tipo subyacente es un objeto genérico? –

8

No estoy seguro de lo bien que esto se escalaría, pero podría usar un convertidor para llegar a su DisplayName. El convertidor sería algo como:

public class DisplayNameConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     PropertyInfo propInfo = value.GetType().GetProperty(parameter.ToString()); 
     var attrib = propInfo.GetCustomAttributes(typeof(System.ComponentModel.DisplayNameAttribute), false); 

     if (attrib.Count() > 0) 
     { 
      return ((System.ComponentModel.DisplayNameAttribute)attrib.First()).DisplayName; 
     } 

     return String.Empty; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

y luego su unión en XAML se vería así:

Text="{Binding Mode=OneWay, Converter={StaticResource ResourceKey=myConverter}, ConverterParameter=MyPropertyName}"