2012-11-27 62 views
11

我有一個簡單的數據結構類:當AutoGenerateColumns = True時,如何重命名DataGrid列?

public class Client { 
    public String name {set; get;} 
    public String claim_number {set; get;} 
} 

對此我送入一個DataGrid

this.data_grid_clients.ItemSource = this.clients; 

我想更改列標題。即:claim_number爲「索賠號碼」。我知道這是可以做到,當你手工做類似創建列:

this.data_grid_clients.Columns[0].Header = "Claim Number" 

然而,Columns屬性爲空生成自動的列時。有沒有辦法重新命名列,或者我必須手動生成列?

+0

如果你需要做的唯一定製是頭重命名和你不怕額外的事件處理程序 - EKK的答案是要走的路。 但是,如果定製其他任何東西(單元格模板,列要顯示)甚至有一點可能性,最好明確列出狀態最近,如果類似的要求會提高,您將被迫重寫代碼或添加類似構造來編輯/重新創建自動生成的列 – Nogard

+0

謝謝,這是有道理的。鑑於我可能會做更多的定製,我可能會手動添加每一列。 – jmulmer

回答

32

您可以使用DisplayNameAttribute並更新您的代碼的一部分來實現您想要的。

你必須做的第一件事是,增加了[DisplayName("")]在客戶端類的屬性。

public class Client { 
    [DisplayName("Column Name 1")] 
    public String name {set; get;} 

    [DisplayName("Clain Number")] 
    public String claim_number {set; get;} 
} 

更新您的xaml代碼,將事件處理程序添加到AutoGenerationColumn事件中。

<dg:DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="OnAutoGeneratingColumn"> 
</dg:DataGrid> 

最後,在代碼隱藏中添加一個方法。

private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
{ 
    var displayName = GetPropertyDisplayName(e.PropertyDescriptor); 

    if (!string.IsNullOrEmpty(displayName)) 
    { 
     e.Column.Header = displayName; 
    } 

} 

public static string GetPropertyDisplayName(object descriptor) 
{ 
    var pd = descriptor as PropertyDescriptor; 

    if (pd != null) 
    { 
     // Check for DisplayName attribute and set the column header accordingly 
     var displayName = pd.Attributes[typeof(DisplayNameAttribute)] as DisplayNameAttribute; 

     if (displayName != null && displayName != DisplayNameAttribute.Default) 
     { 
      return displayName.DisplayName; 
     } 

    } 
    else 
    { 
     var pi = descriptor as PropertyInfo; 

     if (pi != null) 
     { 
      // Check for DisplayName attribute and set the column header accordingly 
      Object[] attributes = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true); 
      for (int i = 0; i < attributes.Length; ++i) 
      { 
       var displayName = attributes[i] as DisplayNameAttribute; 
       if (displayName != null && displayName != DisplayNameAttribute.Default) 
       { 
        return displayName.DisplayName; 
       } 
      } 
     } 
    } 

    return null; 
} 
+0

謝謝,這樣做!我很欣賞乾淨的代碼 - 這使得閱讀起來更容易。 – jmulmer

+0

這就是它!允許跨應用程序重用相同的窗口/數據網格。 – AndrewK

+0

美麗的代碼。感謝百萬@Ekk! –

2

可以使用AutoGeneratingColumns事件。

private void dataGridAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
{ 
    if (e.PropertyName.StartsWith("MyColumn") 
    e.Column.Header = "Anything I Want"; 
} 
+0

這實際上不回答OP問題。 – WoIIe

0

我重構EKK的回答更短的和ReSharper的兼容的解決方案:

public static string GetPropertyDisplayName(object descriptor) 
{ 
    var propertyDescriptor = descriptor as PropertyDescriptor; 
    if (propertyDescriptor != null) 
    { 
     var displayName = propertyDescriptor.Attributes[typeof(DisplayNameAttribute)] as DisplayNameAttribute; 
     if (displayName != null && !Equals(displayName, DisplayNameAttribute.Default)) 
     { 
     return displayName.DisplayName; 
     } 
    } 
    else 
    { 
     var propertyInfo = descriptor as PropertyInfo; 
     if (propertyInfo != null) 
     { 
     var attributes = propertyInfo.GetCustomAttributes(typeof(DisplayNameAttribute), true); 
     foreach (object attribute in attributes) 
     { 
      var displayName = attribute as DisplayNameAttribute; 
      if (displayName != null && !Equals(displayName, DisplayNameAttribute.Default)) 
      { 
       return displayName.DisplayName; 
      } 
     } 
     } 
    } 
    return null; 
} 
1

的漂亮的答案

您可以修改汽車的HeaderAutoGeneratingColumn事件產生DataGridColumn頭,在那裏你可以訪問DisplayNameAttribute

ç lient.cs

public class Client 
{ 
    [DisplayName("Name")] 
    public String name { set; get; } 

    [DisplayName("Claim Number")] 
    public String claim_number { set; get; } 
} 

的.xaml

<DataGrid ItemSource="{Binding Clients}" 
      AutoGenerateColumns="True" 
      AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" /> 

.xaml.cs

V1

// This snippet can be used if you can be sure that every 
// member will be decorated with a [DisplayNameAttribute] 
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    => e.Column.Header = ((PropertyDescriptor)e.PropertyDescriptor).DisplayName; 

V2

// This snippet is much safer in terms of preventing unwanted 
// Exceptions because of missing [DisplayNameAttribute]. 
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
{ 
    if (e.PropertyDescriptor is PropertyDescriptor descriptor) 
    { 
     e.Column.Header = descriptor.DisplayName ?? descriptor.Name; 
    } 
} 
0

簡短的回答

您可以修改汽車的Header產生DataGridColumn頭中的AutoGeneratingColumn事件。

的.xaml

<DataGrid ItemSource="{Binding Clients}" 
      AutoGenerateColumns="True" 
      AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" /> 

.xaml.cs

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
{ 
    switch (e.Name) 
    { 
     case nameof(Client.name): 
      e.Column.Header = "Name"; 
      break; 

     case nameof(Client.claim_number): 
      e.Column.Header = "Claim Number"; 
      break; 
    } 
} 
相關問題