DataGridコントロールは、表示するフィールドと対応するタイトルを手動で宣言するか、データソースをバインドした後に列を自動的に生成するかを選択できます。
ただし、自動モードでは、列見出しはフィールドの名前であり、データソースのすべての列が生成されます。自動モードで特定の判断と操作が必要な場合は、次のような効果的な方法が考えられます。
1.いくつかの列を非表示にします
DataGridのAutoGeneratingColumnイベントを使用して、列を生成するときに不要な列を除外します。
フロントエンド:
<DataGrid>
ItemsSource="{Binding 数据源列表}"
AutoGenerateColumns="True"
AutoGeneratingColumn="gridWC_AutoGeneratingColumn" >
</DataGrid>
舞台裏:
private void gridWC_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.Column.Header.ToString()=="字段一" || e.Column.Header.ToString() == "字段二" || e.Column.Header.ToString() == "字段三")
{
e.Cancel = true;
}
}
2.説明
DataGridは、自動生成された列に関連する2つのイベントを提供します。
AutoGeneratingColumn:属性ごとに列が作成されるときに発生します。発生すると、列が作成されます。このイベントでは、次のことができます。
- 作成した列オブジェクトをe.Columnから取得し、変更します。
- e.Cancelをtrueに設定して、列を破棄します。
- e.Cancelをtrueに設定しない場合、DataGridはイベントの直後に列を列に追加します。
- e.PropertyDescriptorを使用すると、属性が現在列を作成している理由と、属性が所有する属性セットを含む属性の詳細情報を知ることができます。
AutoGeneratedColumns:すべての属性の列の作成が完了すると発生します。
3.列の順序を調整します
-
属性で使用できるカスタム属性を作成します。この属性には、すべての列に対する属性の自動作成列の位置を示す値が含まれています。
-
ではAutoGeneratingColumnのイベント:
-
- e.Cancelをtrueに設定すると、DataGridは、自動的に作成されたすべての列がキャンセル(破棄)されたと見なします。
-
- e.PropertyDescriptorを介してカスタム属性を読み取り、そこから位置情報を抽出します。
-
- 場所情報と列オブジェクトを保存します。
-
- AutoGeneratedColumnsイベントで保存された列のセットを並べ替えてから、それらすべてをDataGrid.Columnsに順番に追加します
3.1主な実装コード
internal class DemoViewModel
{
#region ColumnOrder
//使用 DataGridColumnOrderAttribute 设置自动生成列的顺序
//Use the DataGridColumnOrderAttribute to set the order in which columns are automatically generated
[DataGridColumnOrder(3)]
public string ColumnA {
get; set; }
[DataGridColumnOrder(2)]
public bool ColumnB {
get; set; }
[DataGridColumnOrder(1)]
public DateTime ColumnC {
get; set; }
#endregion ColumnOrder
//使用 DisplayNameAttribute 设置自动生成列的显示名称
//Use DisplayNameAttribute to set the display name(Header) of the automatically generated column
[DisplayName("The DisplayName :)")]
public string ColumnD {
get; set; }
//使用 DoNotAutoGenerateDataGridColumnAttribute 阻止自动生成列
//Block auto generate column with DoNotAutoGenerateDataGridColumnAttribute
[DoNotAutoGenerateDataGridColumn]
public string ColumnE {
get; set; }
public static List<DemoViewModel> GetDemoList() => new List<DemoViewModel>()
{
new DemoViewModel()
{
ColumnA="DemoItem1",
ColumnB =true,
ColumnC =DateTime.Now
}
};
}
/// <summary>
/// 指定属性在System.Windows.Controls.DataGrid中自动生成列时,列的顺序
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class DataGridColumnOrderAttribute : Attribute
{
public static readonly DataGridColumnOrderAttribute Default = new DataGridColumnOrderAttribute(0);
public DataGridColumnOrderAttribute(int order)
{
DataGridColumnOrderValue = order;
}
public virtual int DataGridColumnOrder => DataGridColumnOrderValue;
protected int DataGridColumnOrderValue {
get; set; }
public override bool Equals(object obj)
{
if (obj == this)
{
return true;
}
return obj is DataGridColumnOrderAttribute other && other.DataGridColumnOrder == DataGridColumnOrder;
}
public override int GetHashCode()
{
return DataGridColumnOrder.GetHashCode();
}
public override bool IsDefaultAttribute()
{
return Equals(Default);
}
}
public class DataGridEx : DataGrid
{
private List<ColumnAndOrder> _columnAndOrderList = new List<ColumnAndOrder>();
public DataGridEx()
{
AutoGeneratingColumn += DataGridEx_AutoGeneratingColumn;
AutoGeneratedColumns += DataGridEx_AutoGeneratedColumns;
}
private void DataGridEx_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
//将创建过程标记为已取消,以阻止DataGrid将生成的列对象加入到列集合中.
//Set event to cancel,DataGrid will not add current column to the Columns collection.
e.Cancel = true;
//从Attribute中读取显示名称.
//Read display name from Attribute.
var displayName = ((System.ComponentModel.MemberDescriptor)e.PropertyDescriptor).DisplayName;
if (!string.IsNullOrWhiteSpace(displayName))
{
e.Column.Header = displayName;
}
//从Attribute中读取顺序,以及是否自动生成列的标识.
//Read order from Attribute and whether to automatically generate column.
var attributes = ((System.ComponentModel.MemberDescriptor)e.PropertyDescriptor).Attributes;
var order = 0;
foreach (Attribute attribute in attributes)
{
if (attribute is DataGridColumnOrderAttribute orderAttribute)
{
order = orderAttribute.DataGridColumnOrder;
}
else if (attribute is DoNotAutoGenerateDataGridColumnAttribute)
{
//发现 DoNotAutoGenerateDataGridColumnAttribute 时,丢弃已生成的列
//Discard generated column when DoNotAutoGenerateDataGridColumnAttribute is found
return;
}
}
//将创建的列及顺序保存
//Save the column and order
_columnAndOrderList.Add(new ColumnAndOrder(order, e.Column));
}
private void DataGridEx_AutoGeneratedColumns(object sender, EventArgs e)
{
//按顺序将所有列加入到Columns集合中
//Add all columns to the Columns collection in order
foreach (var columnAndOrder in _columnAndOrderList.OrderBy(v => v.Order))
{
Columns.Add(columnAndOrder.DataGridColumn);
}
//不需要了
//No longer useful
_columnAndOrderList = null;
}
private class ColumnAndOrder
{
public ColumnAndOrder(int order, DataGridColumn dataGridColumn)
{
Order = order;
DataGridColumn = dataGridColumn;
}
public int Order {
get; }
public DataGridColumn DataGridColumn {
get; }
}
}