如何重命名列 DataGrid, 如果一个 AutoGenerateColumns = True?

我有一个简单的数据结构:


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


哪个我雾
DataGrid

:


this.data_grid_clients.ItemSource = this.clients;


我想更改列的头条新闻。 T. e: claim_number 在 "Claim Number". 我知道手动创建列时可以完成这一点,制作类似的东西:


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


但是,财产
Columns

空与自动列生成。 有没有办法重命名列或者我需要手动生成列吗?
已邀请:

龙天

赞同来自:

您可以使用
http://msdn.microsoft.com/en-u ... .aspx
并更新代码的某些部分以实现所需的代码。

您需要做的第一件事是添加
[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;
}

江南孤鹜

赞同来自:

好答案

你可以改变
https://msdn.microsoft.com/en- ... .aspx
自动生成标题
DataGridColumn

在事件中
AutoGeneratingColumn

, 您可以在哪里访问
https://msdn.microsoft.com/en- ... .aspx
Client.cs


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

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


.xaml


<datagrid autogeneratecolumns="True" autogeneratingcolumn="DataGrid_AutoGeneratingColumn" itemsource="{Binding Clients}"></datagrid>


.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;
}
}

风见雨下

赞同来自:

您可以使用该活动 AutoGeneratingColumns.


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

窦买办

赞同来自:

MVVM 回复

根据模板保存它 MVVM 并避免使用可怕的代码,您可以使用自定义行为 Sytem.Windows.Interactivity /一部分表达 Blend SDK, 在发现 nuget/. 你还需要 Windows.Base.dll 在您创建行为的项目中。

XAML


<datagrid autogeneratecolumns="True">
<i:interaction.behaviors>
<behaviours:columnheaderbehaviour></behaviours:columnheaderbehaviour>
</i:interaction.behaviors>
</datagrid>


行为班


public class ColumnHeaderBehaviour : Behavior<datagrid>
{
protected override void OnAttached//
{
AssociatedObject.AutoGeneratingColumn += OnGeneratingColumn;
}

protected override void OnDetaching//
{
AssociatedObject.AutoGeneratingColumn -= OnGeneratingColumn;
}

private static void OnGeneratingColumn/object sender, DataGridAutoGeneratingColumnEventArgs eventArgs/
{
if /eventArgs.PropertyDescriptor is PropertyDescriptor descriptor/
{
eventArgs.Column.Header = descriptor.DisplayName ?? descriptor.Name;
}
else
{
eventArgs.Cancel = true;
}
}
}


行为非常有用,不一定应该在与视图中的相同项目中定义,这意味着您可以创建行为库并在许多应用程序中使用它们。
</datagrid>

小姐请别说爱

赞同来自:

答案

你可以改变
https://msdn.microsoft.com/en- ... .aspx
自动生成标题
DataGridColumn

在事件中
AutoGeneratingColumn

.

.xaml


<datagrid autogeneratecolumns="True" autogeneratingcolumn="DataGrid_AutoGeneratingColumn" itemsource="{Binding Clients}"></datagrid>


.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;
}
}

小明明

赞同来自:

我重申了答案 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;
}

小姐请别说爱

赞同来自:

另一种生成列标题的方法

添加到其他人在加入该方法的上下文中宣布的事实 OnAutoGeneratingColumn, 我发现下一个方法有用。

他将保证他使用该属性 DisplayName 从演示模型的属性就像其他一样,但如果未指定此名称,则将使用正则表达式来获取名称 Pascal cased 并将其变成一个好的柱子标题。


//Note that I cleaned this up after I pasted it into the Stackoverflow Window, I don't
//think I caused any compilation errors but you have been warned.
private void InvoiceDetails_OnAutoGeneratingColumn/object sender,
DataGridAutoGeneratingColumnEventArgs e/
{
if /!/e.PropertyDescriptor is PropertyDescriptor descriptor// return;

//You cannot just use descriptor.DisplayName because it provides you a value regardless to it
// being manually set. This approach only uses a DisplayName that was manually set on a view
// model property.
if /descriptor.Attributes[typeof/DisplayNameAttribute/]
is DisplayNameAttribute displayNameAttr
&& !string.IsNullOrEmpty/displayNameAttr.DisplayName//
{
e.Column.Header = displayNameAttr.DisplayName;
return;
}

//If you only wanted to display columns that had DisplayName set you could collapse the ones
// that didn't with this line.
//e.Column.Visibility = Visibility.Collapsed;
//return;

//This alternative approach uses regular expressions and does not require
//DisplayName be manually set. It will Breakup Pascal named variables
//"NamedLikeThis" into nice column headers that are "Named Like This".
e.Column.Header = Regex.Replace/descriptor.Name,
@"//?<=[A-Z]//[A-Z]//?=[a-z]//|//?<=[a-z]+//[A-Z]//",
@" $0",
RegexOptions.Compiled/
.Trim//;

}

要回复问题请先登录注册