Сортировка Столбца DataGridView с Бизнес-объектами

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

5
задан Sam Mackrill 11 November 2008 в 13:58
поделиться

7 ответов

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

Лучший способ состоит в том, чтобы расширить BindingList и сделать тех, которые после вещей:

protected override bool SupportsSearchingCore
{
    get
    {
        return true;
    }
}

protected override bool SupportsSortingCore
{
    get { return true; }
}

Необходимо будет также реализовать код банка:

ListSortDirection sortDirectionValue;
PropertyDescriptor sortPropertyValue;

protected override void ApplySortCore(PropertyDescriptor prop, 
    ListSortDirection direction)
{
    sortedList = new ArrayList();

    // Check to see if the property type we are sorting by implements
    // the IComparable interface.
    Type interfaceType = prop.PropertyType.GetInterface("IComparable");

    if (interfaceType != null)
    {
        // If so, set the SortPropertyValue and SortDirectionValue.
        sortPropertyValue = prop;
        sortDirectionValue = direction;

        unsortedItems = new ArrayList(this.Count);

        // Loop through each item, adding it the the sortedItems ArrayList.
        foreach (Object item in this.Items) {
            sortedList.Add(prop.GetValue(item));
            unsortedItems.Add(item);
        }
        // Call Sort on the ArrayList.
        sortedList.Sort();
        T temp;

        // Check the sort direction and then copy the sorted items
        // back into the list.
        if (direction == ListSortDirection.Descending)
            sortedList.Reverse();

        for (int i = 0; i < this.Count; i++)
        {
            int position = Find(prop.Name, sortedList[i]);
            if (position != i) {
                temp = this[i];
                this[i] = this[position];
                this[position] = temp;
            }
        }

        isSortedValue = true;

        // Raise the ListChanged event so bound controls refresh their
        // values.
        OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
    }
    else
        // If the property type does not implement IComparable, let the user
        // know.
        throw new NotSupportedException("Cannot sort by " + prop.Name +
            ". This" + prop.PropertyType.ToString() + 
            " does not implement IComparable");
}

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

9
ответ дан 18 December 2019 в 07:11
поделиться

Решением Daok является правильное. Это - также очень часто больше работы, чем это стоит.

Способ ленивого человека получить функциональность, которую Вы хотите, состоит в том, чтобы создать и заполнить DataTable прочь Ваших бизнес-объектов и связать DataGridView с этим.

Существует много вариантов использования, как которые этот подход не обработает (редактируя), и он, очевидно, напрасно тратит время, и расположить с интервалами. Как я сказал, это лениво.

Но легко записать, и получающийся код является проклятым видом, менее таинственным, чем реализация IBindingList.

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

5
ответ дан 18 December 2019 в 07:11
поделиться

Один из самых легких путей состоит в том, чтобы использовать класс BindingListView для обертывания списка DisplayJobs. Класс реализует некоторые необходимые интерфейсы, которые позволяют сортировать и просочиться DataGridView. Это - быстрый путь. Это работает вполне прилично, хотя - единственный протест состоит в том, что при кастинге вещей из DataGridView, необходимо бросить к интерфейсному объекту (ObjectView) вместо фактического объекта (DisplayJob).

Менее ленивый путь состоит в том, чтобы создать пользовательское время набора, которое реализует IBindingList, реализовывая методы сортировки там.

3
ответ дан 18 December 2019 в 07:11
поделиться

Я полагаю, что Ваш класс должен реализовать IComparable интерфейс.

Надежда это помогает,

Bruno Figueiredo

1
ответ дан 18 December 2019 в 07:11
поделиться

Статья MS, предложенная Даоком, получила меня на правильном пути, но я не был удовлетворен реализацией MSS WorkableSearchableList. Я считаю, что реализация очень странная, и она не работала хорошо, когда в колонке есть дубликаты значения. Он также не переопределяет ISSORTEDCORE, который, кажется, требуется DatagridView. Если ISSORTEDCORE не отменяется, поисковый глиф не появляется и переключается между восходящим и нисходящим не работает.

Смотрите мою версию сортиарэрэиста ниже. В knatysortcore () его сортирует использование делегата сравнения, установленного в анонимный метод. Эта версия также поддерживает настройку пользовательских сравнений для определенного свойства, которое может быть добавлено полученным классом с помощью AddCustomCompare ().

Я не уверен, что уведомление об авторских правах все еще применяется, но я только что оставил его.

//---------------------------------------------------------------------
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// 
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Collections;

namespace SomethingSomething
{
    /// <summary>
    /// Supports sorting of list in data grid view.
    /// </summary>
    /// <typeparam name="T">Type of object to be displayed in data grid view.</typeparam>
    public class SortableSearchableList<T> : BindingList<T>
    {
        #region Data Members

        private ListSortDirection _sortDirectionValue;
        private PropertyDescriptor _sortPropertyValue = null;

        /// <summary>
        /// Dictionary from property name to custom comparison function.
        /// </summary>
        private Dictionary<string, Comparison<T>> _customComparisons = new Dictionary<string, Comparison<T>>();

        #endregion

        #region Constructors

        /// <summary>
        /// Default constructor.
        /// </summary>
        public SortableSearchableList()
        {
        }

        #endregion

        #region Properties

        /// <summary>
        /// Indicates if sorting is supported.
        /// </summary>
        protected override bool SupportsSortingCore
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Indicates if list is sorted.
        /// </summary>
        protected override bool IsSortedCore
        {
            get
            {
                return _sortPropertyValue != null;
            }
        }

        /// <summary>
        /// Indicates which property the list is sorted.
        /// </summary>
        protected override PropertyDescriptor SortPropertyCore
        {
            get
            {
                return _sortPropertyValue;
            }
        }

        /// <summary>
        /// Indicates in which direction the list is sorted on.
        /// </summary>
        protected override ListSortDirection SortDirectionCore
        {
            get
            {
                return _sortDirectionValue;
            }
        }

        #endregion

        #region Methods       

        /// <summary>
        /// Add custom compare method for property.
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="compareProperty"></param>
        protected void AddCustomCompare(string propertyName, Comparison<T> comparison)
        {
            _customComparisons.Add(propertyName, comparison);
        }

        /// <summary>
        /// Apply sort.
        /// </summary>
        /// <param name="prop"></param>
        /// <param name="direction"></param>
        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            Comparison<T> comparison;
            if (!_customComparisons.TryGetValue(prop.Name, out comparison))
            {
                // Check to see if the property type we are sorting by implements
                // the IComparable interface.
                Type interfaceType = prop.PropertyType.GetInterface("IComparable");
                if (interfaceType != null)
                {
                    comparison = delegate(T t1, T t2)
                        {
                            IComparable val1 = (IComparable)prop.GetValue(t1);
                            IComparable val2 = (IComparable)prop.GetValue(t2);
                            return val1.CompareTo(val2);
                        };
                }
                else
                {
                    // Last option: convert to string and compare.
                    comparison = delegate(T t1, T t2)
                        {
                            string val1 = prop.GetValue(t1).ToString();
                            string val2 = prop.GetValue(t2).ToString();
                            return val1.CompareTo(val2);
                        };
                }
            }

            if (comparison != null)
            {
                // If so, set the SortPropertyValue and SortDirectionValue.
                _sortPropertyValue = prop;
                _sortDirectionValue = direction;

                // Create sorted list.
                List<T> _sortedList = new List<T>(this);                   
                _sortedList.Sort(comparison);

                // Reverse order if needed.
                if (direction == ListSortDirection.Descending)
                {
                    _sortedList.Reverse();
                }

                // Update list.
                int count = this.Count;
                for (int i = 0; i < count; i++)
                {
                    this[i] = _sortedList[i];
                }

                // Raise the ListChanged event so bound controls refresh their
                // values.
                OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
        }

        // Method below was in the original implementation from MS. Don't know what it's for.
        // -- Martijn Boeker, Jan 21, 2010

        //protected override void RemoveSortCore()
        //{
        //    //int position;
        //    //object temp;
        //    //// Ensure the list has been sorted.
        //    //if (unsortedItems != null)
        //    //{
        //    //    // Loop through the unsorted items and reorder the
        //    //    // list per the unsorted list.
        //    //    for (int i = 0; i < unsortedItems.Count; )
        //    //    {
        //    //        position = this.Find(SortPropertyCore.Name,
        //    //            unsortedItems[i].GetType().
        //    //            GetProperty(SortPropertyCore.Name).
        //    //            GetValue(unsortedItems[i], null));
        //    //        if (position >= 0 && position != i)
        //    //        {
        //    //            temp = this[i];
        //    //            this[i] = this[position];
        //    //            this[position] = (T)temp;
        //    //            i++;
        //    //        }
        //    //        else if (position == i)
        //    //            i++;
        //    //        else
        //    //            // If an item in the unsorted list no longer exists, delete it.
        //    //            unsortedItems.RemoveAt(i);
        //    //    }
        //    //    OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
        //    //}
        //}

        /// <summary>
        /// Ability to search an item.
        /// </summary>
        protected override bool SupportsSearchingCore
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Finds an item in the list.
        /// </summary>
        /// <param name="prop"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        protected override int FindCore(PropertyDescriptor prop, object key)
        {
            // Implementation not changed from MS example code.

            // Get the property info for the specified property.
            PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
            T item;

            if (key != null)
            {
                // Loop through the the items to see if the key
                // value matches the property value.
                for (int i = 0; i < Count; ++i)
                {
                    item = (T)Items[i];
                    if (propInfo.GetValue(item, null).Equals(key))
                        return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// Finds an item in the list.
        /// </summary>
        /// <param name="prop"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private int Find(string property, object key)
        {
            // Implementation not changed from MS example code.

            // Check the properties for a property with the specified name.
            PropertyDescriptorCollection properties =
                TypeDescriptor.GetProperties(typeof(T));
            PropertyDescriptor prop = properties.Find(property, true);

            // If there is not a match, return -1 otherwise pass search to
            // FindCore method.
            if (prop == null)
                return -1;
            else
                return FindCore(prop, key);
        }

        #endregion
    }
}
3
ответ дан 18 December 2019 в 07:11
поделиться

Чтобы решить другую половину вашего вопроса: «Должен ли я подавить это?» -

Да. На мой взгляд, это ужасное предупреждение. SerialVersionUID должен по умолчанию не использовать , не наоборот, а не наоборот.

Если вы не добавляете SerialVersionUID, худшее, что происходит, состоит в том, что две версии объекта, которые на самом деле совместимы с сериализацией, считаются несовместимыми. SerialVersionuit - это способ заявить, что совместимость сериализации не изменилась, переопределяя оценку Java по умолчанию.

Использование SerialVersionUID, худшее, что происходит, является то, что вы случайно не можете обновить идентификатор, когда сериализованная форма класса изменяется несовместимым способом. В лучшем случае вы также получаете ошибку выполнения. В худшее, что-то хуже случается. И представьте, насколько легко не удалось обновить его.

-121--2551503-

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

Как только вы определили два места, единственная проблема для вас - определить ближайший маршрут. Теперь эта проблема заключается в нахождении кратчайшего пути между двумя точками, имеющими многоугольные блоки между ними (которые соответствуют местам, которые не содержат дорог), а единственные возможные соединения - это дороги. Это известная проблема, и существуют эффективные алгоритмы для решения этого.

Я не уверен, что это то, что делает Google, но я надеюсь, что они что-то сделают на этих строках.

Я принимаю вычислительную геометрию в этом семестре. Вот ссылка курса: http://www.ams.sunysb.edu/~jsbm/courses/545/ams545.html . Проверьте их, если вы заинтересованы.

-121--4349598- [11349598-

Я бы порекомендовал замена:

jobs = new List<DisplayJob>();

с:

jobs = new SortableBindingList<DisplayJob>();

Код для SORTALABLEBINDINGLIST является здесь: http://www.timvw.be/preesenting-the-sortablebindinglistttt

Я использовал код на основе этого в производстве без каких-либо проблем. Это единственное ограничение - это то, что это не стабильное сортировка.

Если вы хотите, чтобы быть стабильным, заменить:

itemsList.Sort(delegate(T t1, T t2)
{
    object value1 = prop.GetValue(t1);
    object value2 = prop.GetValue(t2);

    return reverse * Comparer.Default.Compare(value1, value2);
});

с помощью вставки:

int j;
T index;
for (int i = 0; i < itemsList.Count; i++)
{
    index = itemsList[i];
    j = i;

    while ((j > 0) && (reverse * Comparer.Default.Compare(prop.GetValue(itemsList[j - 1]), prop.GetValue(index)) > 0))
    {
        itemsList[j] = itemsList[j - 1];
        j = j - 1;
    }

    itemsList[j] = index;
}
1
ответ дан 18 December 2019 в 07:11
поделиться

Martijn Excelent код, но только одна деталь вам нужно проверить нулевые клетки или пустые :)

if (!_customComparisons.TryGetValue(prop.Name, out comparison))
{
    // Check to see if the property type we are sorting by implements
    // the IComparable interface.
    Type interfaceType = prop.PropertyType.GetInterface("IComparable");
    if (interfaceType != null)
    {
        comparison = delegate(T t1, T t2)
            {
                IComparable val1 = (IComparable)prop.GetValue(t1) ?? "";
                IComparable val2 = (IComparable)prop.GetValue(t2) ?? "";
                return val1.CompareTo(val2);
            };
    }
    else
    {
        // Last option: convert to string and compare.
        comparison = delegate(T t1, T t2)
            {
                string val1 = (prop.GetValue(t1) ?? "").ToString();
                string val2 = (prop.GetValue(t2) ?? "").ToString();
                return val1.CompareTo(val2);
            };
    }
}

Это удача

0
ответ дан 18 December 2019 в 07:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: