我注意到SL3 Validators在创建验证消息时会自动使用DisplayAttribute中的属性。我对如何使用代码从控件绑定中提取此信息的任何建议感兴趣。我举了一个例子:
ViewModel代码:
[Display(Name="First Name")]
public string FirstName { get; set; }
我知道可以在Control-by-Control的基础上实现这一点,如下所示(在本例中为TextBox):
BindingExpression dataExpression = _firstNameTextBox.GetBindingExpression(TextBox.TextProperty)
Type dataType = dataExpression.DataItem.GetType();
PropertyInfo propInfo = dataType.GetProperty(dataExpression.ParentBinding.Path.Path);
DisplayAttribute attr = propInfo.GetCustomAttributes(false).OfType<DisplayAttribute>().FirstOrDefault();
return (attr == null) ? dataExpression.ParentBinding.Path.Path : attr.Name;
我很感兴趣,如果有任何方法可以做到这一点,而不需要知道具体的控制类型。
提前感谢任何想法!!
答案 0 :(得分:1)
好问题。不幸的是,虽然你可以硬编码一些属性并且非常安全,但实际上没有办法一般地做到这一点。例如,ContentControl.ContentProperty,TextBlock.TextProperty,TextBox.TextProperty等。
Silverlight中的DataForm也做同样的事情。我还重新实现了一个名为GetPropertyByPath的简单助手方法。它基本上做了你的代码所做的事情,除了它可以走多步属性路径。它无法访问索引属性,但DataForm也无法访问索引属性。
从那时起,获取DisplayAttribute正如您所示。
public static PropertyInfo GetPropertyByPath( object obj, string propertyPath )
{
ParameterValidation.ThrowIfNullOrWhitespace( propertyPath, "propertyPath" );
if ( obj == null ) {
return null;
} // if
Type type = obj.GetType( );
PropertyInfo propertyInfo = null;
foreach ( var part in propertyPath.Split( new char[] { '.' } ) ) {
// On subsequent iterations use the type of the property
if ( propertyInfo != null ) {
type = propertyInfo.PropertyType;
} // if
// Get the property at this part
propertyInfo = type.GetProperty( part );
// Not found
if ( propertyInfo == null ) {
return null;
} // if
// Can't navigate into indexer
if ( propertyInfo.GetIndexParameters( ).Length > 0 ) {
return null;
} // if
} // foreach
return propertyInfo;
}