C # Сортировка DataGridView с общим списком в качестве основного источника

17

Я использую Windows Forms DataGridView , чтобы отобразить общий список объектов MyObject .

Прежде всего, я переношу эту коллекцию в коллекцию BindingSource , а затем:

dataGridView.DataSource = myBindingSource;

Что я хочу сделать, так это разрешить пользователю сортировать столбцы, щелкнув по заголовку столбца, представляющего конкретное свойство в MyObject.

Я прочитал несколько статей, которые мне нужно будет сортировать перед привязкой. Но это не помогает мне, если я хочу сортировать столбцы в реальном времени, будучи сказанным, когда он уже привязан.

Вопрос в том, что именно мне нужно сделать, поэтому я мог видеть стрелки сортировки в DataGridView и , я мог сортировать каждый столбец ?

    
задан PaN1C_Showt1Me 04.09.2009 в 08:34
источник
  • См. stackoverflow.com/questions/3770857/.... Это так же просто, как dataGridView.DataSource = new BindingListView <MyObject> (myObjects.ToList ()) с библиотекой в ​​sourceforge.net/projects/blw. –  Pat 30.07.2013 в 19:01

8 ответов

1

Мое решение таково:

Я работаю с myBindingSource самостоятельно, я сортирую, группирую ... что бы ни было в отдельном потоке. Затем я просто привязываю результат к DataGridView .

myDataGridView.DataSource = bindingSource;

С этой целью я установил все столбцы для сортировки 'Programatically' (в дизайнере) Затем я вручную добавляю стрелку (ASCENDING / DESCENDING) установив

cell.SortGlyphDirection = ... ; 

в коде.

    
ответ дан PaN1C_Showt1Me 14.09.2009 в 14:52
источник
29

Полный код для сортировки столбца datagridview, чей источник данных является общим списком

//-----------------------------------------------------------------------------------------
//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;
        }
    }
    
ответ дан Asish 31.03.2010 в 10:23
источник
  • Отличное решение, спасибо вам большое! Я потратил время и немного улучшил его. –  Nikola Malešević 24.09.2011 в 01:48
7

Мне трудно поверить, что сетка не обеспечивает базовую сортировку из коробки, а не код. В конце концов, довольно глупо обрабатывать событие щелчка заголовка и вызывать DataGridView.Sort, указывающий столбец (определяется тем, что было нажато, отслеживается сеткой) и направлением сортировки (определяется текущим состоянием сортировки, отслеживается сеткой ).

Почему нет просто свойства SortMode или AllowUserToSort, которое по умолчанию делает то же самое?

Я привязал свою сетку к списку, а свойства, с которыми я сопоставил столбцы, - это все базовые типы, такие как string, int, DateTime и т. д. Все из них являются IComparable. Так почему же мне нужно писать даже одну строку кода? Особенно учитывая, что документация гласит:

  

По умолчанию пользователи могут сортировать данные в   элемент управления DataGridView, нажав   заголовок столбца текстового поля.

MSDN

Это документ 3.0 3.0, и я нацелен на 3,5, но «другие версии» относятся ко всем версиям Visual Studio, а не к версиям Framework. Что происходит здесь, Microsoft?!?

    
ответ дан The Dag 27.04.2011 в 18:36
источник
  • BTW Мои столбцы имеют тип DataGridViewTextBoxColumn, который, по-видимому, означает, что MS означает «столбец текстового поля». –  The Dag 27.04.2011 в 18:39
  • Существует SortMode, но он ничего не делает! –  ProfK 25.09.2012 в 14:29
5

Хорошее решение в этой статье «Представление SortableBindingList»: Ссылка

    
ответ дан Juan Camilo Caro 16.07.2011 в 23:52
источник
0

Вы также можете взглянуть на этот пост, где вы можете получить две интересные ссылки для реализации настраиваемого SortableBindingList:

Сортировка столбцов Datagridview при привязке источника данных к Список (Of T)

    
ответ дан alex 04.11.2011 в 09:50
источник
0

см. эту статью

Ссылка

, прочитав его, я увидел это: «Этот метод сортирует содержимое DataGridView, сравнивая значения в указанном столбце. По умолчанию операция сортировки будет использовать метод Compare для сравнения пар ячеек в столбце с помощью DataGridViewCell .. ::. Значение свойства.

С наилучшими пожеланиями, Iordan     

ответ дан IordanTanev 04.09.2009 в 08:45
источник
0

Вот более простое решение для сортировки по столбцу с использованием Reflection и Linq. DataSource dataGridView1 установлен в compareList, который объявляется как:

    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; }
    }
}
    
ответ дан Jeff Qi 29.10.2014 в 15:28
источник
  • Я немного изменил это решение, чтобы получить более быстрый результат. Я использовал DataPropertyName вместо Name для имени strColumnName, и я отбрасывал свой compareList внутри события click вверху: var compareList = (dataGridView1.DataSource как List <myobjecttype>); Это было достаточно для моих потребностей в одноразовом приложении. –  archangel76 13.06.2016 в 22:46
0

Другой вариант решения проблемы сортировки с DataGridView при привязке к List - если вы не имеете дело с огромным набором данных, то, вероятно, вы можете попытаться преобразовать List в DataTable, а затем привязать полученный DataTable к BindingSource / DataGridView ,

Это потребовало бы специальной реализации IComparer. В моем случае я имел дело с меньшим списком, но было больше полей для отображения. Таким образом, реализация IComparer означала запись слишком большого количества кодовых табличек.

Проверьте это для краткого способа преобразования List to DataTable: Ссылка

    
ответ дан Naren 21.09.2017 в 22:29
источник