Вопрос

Я хочу упорядочить ObservableCollection в алфавитном порядке, потому что мне не нужно создавать еще одну привязку.Я видел, что мы могли бы использовать Linq и метод OrderBy.Я также хотел бы использовать личный IComparer, потому что мне придется организовывать сложные данные (списки в другие списки), но VS говорит мне, что я не могу использовать свой собственный компаратор:

(дайте ссылку на ошибку, потому что мой VS на французском языке)

http://msdn.microsoft.com/en-gb/library/hxfhx4sy%28v=vs.90%29.aspx

Есть идеи ?

private void SortGraphicObjectsAscending(object sender, RoutedEventArgs e)
    {
        GraphicObjects.OrderBy(graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

    }

И мой собственный компаратор (который уже опробован)

public class GraphicObjectComparer : IComparer<GraphicObject>
{
    int order = 1;

    public GraphicObjectComparer(Boolean ascending)
    {
        if (!ascending)
        {
            order = -1;
        }
    }

    public GraphicObjectComparer()
    {

    }

    public int Compare(GraphicObject x, GraphicObject y)
    {
        return String.Compare(x.Nom, y.Nom, false) * order;
    }

}

Спасибо за ваши ответы.В любом случае у меня есть другая проблема.Как сказал Майкл, я использую более сложный компаратор, но для другой сущности.Этот объект отображается в виде иерархического дерева, и объект может содержать список других объектов того же типа.

Я не смог протестировать свой GraphicObject, поскольку у меня нет доступа к БД (в данный момент объекта не было).Судя по тестам моего VideoEntity, кажется, что моя ObservableCollection не отсортирована так, как я хочу (я создаю еще одну).Я хочу перевернуть его в алфавитном порядке, но это не работает.

public class VideoEntityComparer : IComparer<VideoEntity>
{

    int order = 1;

    public VideoEntityComparer(Boolean ascending)
    {
        if (!ascending)
        {
            this.order = -1; // so descending
        }
    }

    public VideoEntityComparer()
    {

    }

    public int Compare(VideoEntity x, VideoEntity y)
    {
        if ((x is BaseDirectory && y is BaseDirectory) || (x is BaseSite && y is BaseSite) || (x is VideoEncoder && y is VideoEncoder))
        {
            return string.Compare(x.Nom, y.Nom, false) * order; // only objects of the same type are sorted alphabetically
        }
        else if ((x is BaseDirectory && y is BaseSite) || (x is BaseSite && y is VideoEncoder))
        {
            return -1;
        }else
        {
            return 1;
        }
    }
}

private void SortDirectoriesDescending(object sender, RoutedEventArgs e)
    {
        ObservableCollection<BaseDirectory> tempDir  = new ObservableCollection<BaseDirectory>(
            Directories.OrderBy(directory => directory, new VideoEntityComparer(false)));
        Directories = tempDir;
    }

PS:кстати, я действую на DependancyProperty.Это правильный способ сделать это?(Я новичок в WPF)

Это было полезно?

Решение

Проблема с этой строкой заключается в определении OrderBy что вы пытаетесь использовать:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer
)

В этом методе есть два разных общих параметра: TSource и TKey. TSource очевидно, это то же самое, что TSource для источника IEnumerableTKey Параметр — это тот, который компилятор пытается вывести, но безуспешно, потому что вы пытаетесь использовать два разных типа.Ваш звонок:

GraphicObjects.OrderBy(graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

Ваш первый параметр - это Func<GraphicObject, string> но ваш второй параметр - это IComparer<GraphicObject>;это означает, что вы используете TKey = string в одном месте и TKey = GraphicObject в другом.

Первый параметр, Func<> делегат — «ключевой селектор»;это то, как ты говоришь OrderBy по каким значениям сортировать.Поскольку ваш IComparer<> сортирует по весь GraphicObject пример, это то, что вы должны выбрать в качестве ключа:

GraphicObjects.OrderBy(go => go, new GraphicObjectComparer(true));

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

var asc = GraphicObjects.OrderBy(go => go.Nom);
var desc = GraphicObjects.OrderByDescending(go => go.Nom);

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

Другие советы

твой comparer сравнивает GraphicObject.Так что ваши OrderBy должно быть

 GraphicObjects.OrderBy(graphicObject => graphicObject,
                                                 new GraphicObjectComparer(true));

или просто используйте

GraphicObjects.OrderBy(graphicObject => graphicObject.Nom);

КСТАТИ, OrderBy не сортирует на месте, вам следует назначить возвращаемое IEnumerable<GraphicsObject> в переменную

Проблема в том, что ваш компаратор использует GraphicObject, но вы сравниваете строки.

Если вам действительно нужен ваш собственный заказ, вы можете использовать этот компаратор:

public class GraphicObjectComparer : IComparer<string>
{
    int order = 1;

    public GraphicObjectComparer(Boolean ascending)
    {
        if (!ascending)
        {
            order = -1;
        }
    }

    public GraphicObjectComparer()
    {

    }

    public int Compare(string x, string y)
    {
        return String.Compare(x, y, false) * order;
    }
}
.

Или вы предоставляете графику для вашего компаратора, а не строки.

Для того, чтобы отсортировать обшивку для наблюдения, отражает все изменения в коллекции источника, вы можете использовать My My Обсудообменные компьютеры библиотекаОтказИспользуя эту библиотеку, которую вы можете код, как это:

var sortedGraphicObjects = GraphicObjects.Ordering(
    graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));
.

СортировкаGraphicobjects - это наблюдательное оборудование и отражает все изменения в сборе графиков и свойства NOM.Убедитесь, что NOM имущество уведомляет об изменениях через InotifyPropertyChanged интерфейс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top