English 中文(简体)
C# DataGrid 1. 认为通用清单是基本来源
原标题:C# DataGridView sorting with Generic List as underlying source
  • 时间:2009-09-04 06:34:09
  •  标签:

I m 采用Windows Forms DataGridView显示一个通用的MyObject物体清单。

首先,我把这一收集整理成一个<条码>。 收集:

dataGridView.DataSource = myBindingSource;

我想做的是,允许用户在代表MyObject具体财产的一栏头上点击,对各栏进行分类。

我读过一些条款,我应该先作决定,然后才具有约束力。 但是,如果我想要实时打上一栏,如果说它已经具有约束力的话,这无助于我。

问题是,我究竟需要做些什么? 我可以看到,在数据GridView和中,有 sort。 我可以划分每个栏目?

最佳回答

我的解决办法是:

I work with myBindingSource at my own, I do sorting, grouping ..whatever in a separate thread. Then I simply bind the result to the DataGridView.

myDataGridView.DataSource = bindingSource;

For this purpose I ve setted all the columns to be sorted Programatically (in designer) Then I manually add the arrow (ASCENDING / DESCENDING) by setting

cell.SortGlyphDirection = ... ; 

页: 1

问题回答

统一编码,对数据来源为通用清单的数据组进行分类

//-----------------------------------------------------------------------------------------
//In the form - In constructor or form load, populate the grid.
//--------------------------------------------------------------------------------------------

    List<student> students;

    private void PopulateList()
    {
        student std1 = new student("sss", 15, "Female");
        student std2 = new student("ddd", 12, "Male");
        student std3 = new student("zzz", 16, "Male");
        student std4 = new student("qqq", 14, "Female");
        student std5 = new student("aaa", 11, "Male");
        student std6 = new student("lll", 13, "Female");

        students = new List<student>();
        students.Add(std1);
        students.Add(std2);
        students.Add(std3);
        students.Add(std4);
        students.Add(std5);
        students.Add(std6);

        dataGridView1.DataSource = students;
    }


//---------------------------------------------------------------------------------------------
//Comparer class to perform sorting based on column name and sort order
//---------------------------------------------------------------------------------------------


class StudentComparer : IComparer<Student>
{
    string memberName = string.Empty; // specifies the member name to be sorted
    SortOrder sortOrder = SortOrder.None; // Specifies the SortOrder.

    /// <summary>
    /// constructor to set the sort column and sort order.
    /// </summary>
    /// <param name="strMemberName"></param>
    /// <param name="sortingOrder"></param>
    public StudentComparer(string strMemberName, SortOrder sortingOrder)
    {
        memberName = strMemberName;
        sortOrder = sortingOrder;
    }

    /// <summary>
    /// Compares two Students based on member name and sort order
    /// and return the result.
    /// </summary>
    /// <param name="Student1"></param>
    /// <param name="Student2"></param>
    /// <returns></returns>
    public int Compare(Student Student1, Student Student2)
    {
        int returnValue = 1;
        switch (memberName)
        {
            case "Name" :
                if (sortOrder == SortOrder.Ascending)
                {
                    returnValue = Student1.Name.CompareTo(Student2.Name);
                }
                else
                {
                    returnValue = Student2.Name.CompareTo(Student1.Name);
                }

                break;
            case "Sex":
                if (sortOrder == SortOrder.Ascending)
                {
                    returnValue = Student1.Sex.CompareTo(Student2.Sex);
                }
                else
                {
                    returnValue = Student2.Sex.CompareTo(Student1.Sex);
                }
                break;
            default:
                if (sortOrder == SortOrder.Ascending)
                {
                    returnValue = Student1.Name.CompareTo(Student2.Name);
                }
                else
                {
                    returnValue = Student2.Name.CompareTo(Student1.StudentId);
                }
                break;
        }
        return returnValue;
    }
}



//---------------------------------------------------------------------------------------------
// Performing sort on click on Column Header
//---------------------------------------------------------------------------------------------

    private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        //get the current column details
        string strColumnName = dataGridView1.Columns[e.ColumnIndex].Name;
        SortOrder strSortOrder = getSortOrder(e.ColumnIndex);

        students.Sort(new StudentComparer(strColumnName, strSortOrder));
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = students;
        customizeDataGridView();
        dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
    }

   /// <summary>
    /// Get the current sort order of the column and return it
    /// set the new SortOrder to the columns.
    /// </summary>
    /// <param name="columnIndex"></param>
    /// <returns>SortOrder of the current column</returns>
    private SortOrder getSortOrder(int columnIndex)
    {
        if (dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.None ||
            dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.Descending)
        {
            dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
            return SortOrder.Ascending;
        }
        else
        {
            dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
            return SortOrder.Descending;
        }
    }

我认为,很难相信电网 t不提供从箱子中进行基本分类,不需要任何代码。 毕竟,不得不处理头盔点击事件和打电话数据GridView,是sil笑的。 仅注明一栏(按点击、按电网追踪)和方向(按目前情况确定,由电网跟踪)。

为什么只有SortMode或允许User ToSort地产,而这种财产在违约时确实如此?

我把我的电网连接到一个清单中,而我绘制了一栏图的特性是所有基本类型,如铺设、装设、日期等等。 所有这一切都是可笑的。 因此,为什么在地球上我需要写哪怕一条法典? 尤其考虑到文件如下:

By default, users can sort the data in a DataGridView control by clicking the header of a text box column.

该框架有3.0英亩,Im以3.5为目标,但“其他版本”都指视觉演播室的版本,而不是框架的版本。 在这里,微软公司正在做什么?

此处采用“反思”和“Linq”一栏进行分类的比较简单的解决办法。 数据 GridView1 名单:

    private List<CompareInfo> compareList;


    private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        string strColumnName = dataGridView1.Columns[e.ColumnIndex].Name;
        SortOrder strSortOrder = getSortOrder(e.ColumnIndex);

        if (strSortOrder == SortOrder.Ascending)
        {
            compareList = compareList.OrderBy(x => typeof(CompareInfo).GetProperty(strColumnName).GetValue(x, null)).ToList();
        }
        else
        {
            compareList = compareList.OrderByDescending(x => typeof(CompareInfo).GetProperty(strColumnName).GetValue(x, null)).ToList();
        }
        dataGridView1.DataSource = compareList;
        dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
    }

    private SortOrder getSortOrder(int columnIndex)
    {
        if (dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.None ||
            dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.Descending)
        {
            dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
            return SortOrder.Ascending;
        }
        else
        {
            dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
            return SortOrder.Descending;
        }
    }


public class CompareInfo
{
    public string FileName { get; set; }

    public string UAT_Folder { get; set; }

    public string UAT_Path
    {
        get { return UAT_Folder + FileName; }
    }

    public string PROD_Folder { get; set; }

    public string PROD_Path
    {
        get { return PROD_Folder + FileName; }
    }
}

如果建立你自己的用户控制更为可取,你可以采用以下代码,采用某种习俗:

    private string _lastSortColumn;
    private ListSortDirection _lastSortDirection;

    public void Sort(DataGridViewColumn column)
    {
        // Flip sort direction, if the column chosen was the same as last time
        if (column.Name == _lastSortColumn)
            _lastSortDirection = 1 - _lastSortDirection;
        // Otherwise, reset the sort direction to its default, ascending
        else
        {
            _lastSortColumn = column.Name;
            _lastSortDirection = ListSortDirection.Ascending;
        }

        // Prep data for sorting
        var data = (IEnumerable<dynamic>)DataSource;
        var orderProperty = column.DataPropertyName;

        // Sort data
        if (_lastSortDirection == ListSortDirection.Ascending)
            DataSource = data.OrderBy(x => x.GetType().GetProperty(orderProperty).GetValue(x, null)).ToList();
        else
            DataSource = data.OrderByDescending(x => x.GetType().GetProperty(orderProperty).GetValue(x, null)).ToList();

        // Set direction of the glyph
        Columns[column.Index].HeaderCell.SortGlyphDirection
            = _lastSortDirection == ListSortDirection.Ascending
            ? SortOrder.Ascending : SortOrder.Descending;
    }

那么,你就可以推翻头盔的点击方法,把你的职责称作:

    protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
    {
        base.OnColumnHeaderMouseClick(e);

        var column = Columns[e.ColumnIndex];

        if (column.SortMode == DataGridViewColumnSortMode.Automatic
            || column.SortMode == DataGridViewColumnSortMode.NotSortable)
            Sort(column);
    }

您也不妨看看这个职位,在那个职位上,你可以找到两个令人感兴趣的联系,以实施定制的SortableBledList:

数据来源对清单(Of T)有约束力时的直线数据组:

如果你不处理庞大的数据集,那么另一个解决数据GridView问题的办法就是,如果你不处理巨大的数据集,那么你可能会试图将清单转换成可数据的数据,然后将由此得出的数据与BileSource/DataGridView联系起来。

这需要按惯例执行国际协调委员会。 就我而言,我处理的是一份较小的清单,但还有更多的领域可以显示。 因此,执行国际竞争委员会意味着撰写太多的锅炉板码。

https://stackoverflow.com/a/34062898/4534493>

First of all I used System.Reflection; then: write this method

 public DataTable ToDataTable<T>(List<T> items)
    {
        DataTable dataTable = new DataTable(typeof(T).Name);
        //Get all the properties
        PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | 
        BindingFlags.Instance);

        foreach (PropertyInfo prop in Props)
        {
            //Setting column names as Property names

            dataTable.Columns.Add(prop.Name);
        }
        foreach (T item in items)
        {
            var values = new object[Props.Length];

            for (int i = 0; i < Props.Length; i++)
            {
                //inserting property values to datatable rows

                values[i] = Props[i].GetValue(item, null);
            }
            dataTable.Rows.Add(values);
        }
           //put a breakpoint here and check datatable
        return dataTable;
    }

然后使用方法: DataTable dt = ToDataTable(lst.ToList());

数据的通用分类

private void ItemsTable_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    var sortingColumn = ItemsTable.Columns[e.ColumnIndex];

    var propertyInfo = typeof(ListingInfo).GetProperty(sortingColumn.DataPropertyName);
    if (propertyInfo == null) // ignore columns with buttons or pictures
        return;

    foreach (DataGridViewColumn dataGridViewColumn in ItemsTable.Columns)
    {
        if (dataGridViewColumn != sortingColumn)
            dataGridViewColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
    }
    sortingColumn.HeaderCell.SortGlyphDirection = sortingColumn.HeaderCell.SortGlyphDirection == SortOrder.Ascending
        ? SortOrder.Descending : SortOrder.Ascending;

    _listingsList.Sort((x, y) =>
    {
        var first = sortingColumn.HeaderCell.SortGlyphDirection == SortOrder.Ascending ? x : y;
        var second = sortingColumn.HeaderCell.SortGlyphDirection == SortOrder.Ascending ? y : x;
        var firstValue = propertyInfo.GetValue(first);
        var secondValue = propertyInfo.GetValue(second);
        if (firstValue == null)
            return secondValue == null ? 0 : -1;
        return secondValue == null ? 1 : ((IComparable)firstValue).CompareTo(secondValue);
    });

    // tell the binding list to raise a list change event so that bound controls reflect the new item order
    ItemsTable.ResetBindings();
    ItemsTable.Refresh();
}




相关问题
热门标签