WPF programming, a brief description of hiding some columns or performing other operations when the DataGrid control automatically generates columns

The DataGrid control can choose to manually declare the fields to be displayed and the corresponding titles, or it can automatically generate columns after binding the data source.
However, in automatic mode, the column heading is the name of the field, and all the columns in the data source are generated. If certain judgments and operations are required in automatic mode, here is a possible effective method.

1. Hide some columns

Use the AutoGeneratingColumn event of the DataGrid to filter out unwanted columns when generating columns.

front end:

<DataGrid>  
	ItemsSource="{Binding 数据源列表}"  
	AutoGenerateColumns="True" 
	AutoGeneratingColumn="gridWC_AutoGeneratingColumn" > 
</DataGrid>

Backstage:

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. Explanation

DataGrid provides two events related to automatically generated columns, namely:

AutoGeneratingColumn : It will be raised when the column is created for each attribute. When it is raised, the column has been created. In this event you can:

  • Obtain the created column object through e.Column and modify it.
  • Discard the column by setting e.Cancel to true.
  • If you don't set e.Cancel to true, the DataGrid will immediately add the column to the Columns after the event.
  • Through e.PropertyDescriptor, you can know why the attribute is currently creating the column, and the detailed information of the attribute, including the Attribute set owned by the attribute.

AutoGeneratedColumns : Will be raised when the creation of columns for all attributes is complete.

3. Adjust the order of the columns

The idea is as follows: program sharing , source code sharing

  • Create a custom Attribute that can be used on the attribute, which contains a value to indicate the position of the column automatically created for the attribute relative to all columns.

  • In the AutoGeneratingColumn event:

    • Set e.Cancel to true to make the DataGrid think that all automatically created columns are cancelled (abandoned).
    • Read the custom Attribute through e.PropertyDescriptor and extract the location information from it.
    • Save the location information and column objects.
    • Sort the set of saved columns in the AutoGeneratedColumns event, and then add them all to DataGrid.Columns in order

3.1 The main implementation code

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

Guess you like

Origin blog.csdn.net/qq_43307934/article/details/109034794