2010-03-08 37 views
3

從ViewModel綁定控件檢索System.ComponentModel.DataAnnotations.DisplayAttribute屬性我注意到SL3 Validators在創建驗證消息時自動使用DisplayAttribute中的屬性。我對如何從控件綁定使用代碼中提取這些信息的建議感興趣。我已經包括了一個例子:使用代碼

視圖模型代碼:

[Display(Name="First Name")] 
public string FirstName { get; set; } 

我知道可以在控制按控制基礎上做類似以下內容(在這種情況下,文本框)實現這一點:

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; 

我很感興趣,如果有什麼辦法可以做到這一般,而不需要知道具體的控制類型。

在此先感謝您的任何想法!

回答

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; 

} 
+0

+1 - 我最近寫了類似的東西,做了幾乎相同的事情。我可能會建議的一件事是,如果你需要處理附加屬性,上面的代碼將不起作用(你需要處理括號,比如(Validation.Errors)等)。 – JerKimball 2010-03-08 16:23:39

+0

是的好點。我忘了提及,除了索引屬性,它基本上不能處理任何東西,而不是正常的虛線路徑,這都是DataForm的嘗試。大多數情況下這很好,因爲你通常所做的就是訪問ViewModel屬性。 – Josh 2010-03-08 20:28:48

+0

啊,我忘記了多步驟屬性。感謝摘錄,這非常有幫助。 – Patrick 2010-03-09 00:46:16