WPF编程,DataGrid控件自动生成列时,隐藏部分列或进行其它操作的简要说明

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提供了两个与自动生成列有关的事件,分别是:

AutoGeneratingColumn:会在为每个属性创建列时引发,引发时列已经创建完毕,在这个事件中可以:

  • 通过e.Column获取已经创建的列对象,并对其进行修改.
  • 通过将e.Cancel设为true,以放弃该列.
  • 如果不将e.Cancel设为true,则该事件后DataGrid会立刻将列加入列集合(Columns)中.
  • 通过e.PropertyDescriptor可以知道当前是为什么属性在创建列,以及该属性的细节信息,包括属性所拥的Attribute集合.

AutoGeneratedColumns:会在为所有属性创建列完成时引发。

3、调整列的顺序

思路如下:方案分享,源代码分享

  • 创建一个可以用在属性上的自定义Attribute,其包含一个值,用来表示为属性自动创建的列相对于所有列的位置.

  • AutoGeneratingColumn事件中:

    • 将e.Cancel设为true,使DataGrid认为所有自动创建的列都被取消(放弃)了.
    • 通过e.PropertyDescriptor读取自定义的Attribute,从中取出位置信息.
    • 将位置信息和列对象保存起来.
    • 在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
            }
        };
    }
    /// 
    /// 指定属性在System.Windows.Controls.DataGrid中自动生成列时,列的顺序
    /// 
    [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; }
        }
    }

你可能感兴趣的:(WPF,wpf,C#,DataGrid,自动生成,列)