2

別のバインディングを作成する必要がないため、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;
    }

}

回答ありがとうございます。とにかく、私には別の問題があります。マイケルが言ったように、私はより複雑な比較を使用しますが、別のエンティティを対象としています。このエンティティは階層ツリーで表示され、オブジェクトには同じタイプの他のオブジェクトのリストが含まれる場合があります。

DBにアクセスできないため、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が初めてです)

4

4 に答える 4

3

その行の問題は、OrderBy使用しようとしているの定義にあります。

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

このメソッドには、 と の 2 つの異なる汎用パラメーターがありTSourceますTKey。ソースTSourceの と同じです。パラメーターは、2 つの異なる型を使用しようとしているため、コンパイラーが推論しようとして失敗したパラメーターです。あなたの電話:TSourceIEnumerableTKey

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

最初のパラメーターは aFunc<GraphicObject, string>ですが、2 番目のパラメーターは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 操作は、ソースの列挙型を変更することはありません。代わりに、変換された新しいコピーを常に返します。

于 2012-07-25T16:21:07.547 に答える
1

あなたのcomparer比較GraphicObject。だからあなたはそうOrderByあるべきです

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

または単に使用する

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

ところで、OrderByその場でソートしません。返さIEnumerable<GraphicsObject>れたものを変数に割り当てる必要があります

于 2012-07-25T16:20:33.523 に答える
0

問題は、Comparerが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;
    }
}

または、文字列ではなく、GraphicObjectを比較対象に提供します。

于 2012-07-25T16:24:04.037 に答える