简体   繁体   中英

How to sort a dictionary for TreeView output by Character for character?

Im setting up a treeView list and need to add some new Items. Idea is to create some sort of "billing list" for each day. First the user selects a date on the left side and get a treeView displayed on the right; containing all inserted Bills. To do so, the user can select a Level, a name + amount of money to insert to. The money of all children should be summarized in the respective parent's text data be like Level| Name amount

  • 0| Complete amount xxx€ 1| Shopping 25€ (calculated)
  • 1.1| Aldi 20€ (inserted)
  • 1.2| Lidl 5€ (inserted)
  • 1.2.1| Milka 3€ (inserted)
  • 1.2.2| Bath 2€ (calculated)
  • 1.2.2.1| Toothbrush 1€ (inserted)
  • 1.2.2.2| Soap 1€ (inserted) 2| Car 100€ (calculated)
  • 2.1| Fuel 80€ (inserted)
  • 2.2| washing 20€ (inserted) 3| Dinner
  • 3.1|
  • ....
  • ...
  • ...

so the tree should be extended whenever the user put in(simple pop-up form with 3 textboxes) a new value.

So far, i've created a dictionary of type > The outer Dictionary is to store the items apart from each other, split into each one date. Every day could have another kind of treestructure; the only one beeing on top of every day is "0| Complete amount". the inner dictionary contains the level (0, 1.1, 1.2.2.1...) and all entries for this level.

The problems start and end with the sort of this dictionary. In case it is sorted and will never be touched, everything is ok. But if anything is not in order, I need either a way to sort the dictionary in a correct way, or to iterate over it in the right way.

1.1 sould be before 1.2 and before 2, but after 1.

Given the new dictionary like

  • 1|
  • 1.1|
  • 2|
  • 1.2|
  • 2.1|

after i do the "orderby" it will be the same structure, but I need it to be

  • 1|
  • 1.1|
  • 1.2|
  • 2|
  • 2.1|

Does anyone know, how to reach this? Or is there a way to iterate over all items and add them as child-items in the right order? Or any way to auto-sort the treeview by .split('|')[0]? my items always start with "level + |"

Try IComparable :

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;


namespace ConsoleApplication131
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] inputs = {
                "0| Complete amount xxx€ 1| Shopping 25€ (calculated)",
                "1.1| Aldi 20€ (inserted)",
                "1.2| Lidl 5€ (inserted)",
                "1.2.1| Milka 3€ (inserted)",
                "1.2.2| Bath 2€ (calculated)",
                "1.2.2.1| Toothbrush 1€ (inserted)",
                "1.2.2.2| Soap 1€ (inserted) 2| Car 100€ (calculated)",
                "2.1| Fuel 80€ (inserted)",
                "2.2| washing 20€ (inserted) 3| Dinner"
                             };
            SortParagraph sorter = new SortParagraph();
            List<SortParagraph> sortParagraphs = sorter.ParsePararaph(inputs);

            List<SortParagraph> sortedParagraphs = sortParagraphs.OrderBy(x => x).ToList();

            foreach (SortParagraph sortParagraph in sortedParagraphs)
            {
                Console.WriteLine("Para : '{0}', Titles = '{1}'", string.Join(".", sortParagraph.subParagraphs), string.Join(",", sortParagraph.titles));
            }
            Console.ReadLine();

        }
    }
    public class SortParagraph : IComparable<SortParagraph>
    {
        public int[] subParagraphs { get; set; }
        public string[] titles { get; set; }

        public List<SortParagraph> ParsePararaph(string[] inputs)
        {
            List<SortParagraph> paragraphs = new List<SortParagraph>();
            foreach(string input in inputs)
            {
                SortParagraph newParagraph = new SortParagraph();
                string[] splitParagraph = input.Split(new char[] { '|' }).ToArray();
                newParagraph.titles = splitParagraph.Skip(1).ToArray();
                newParagraph.subParagraphs = splitParagraph.First().Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToArray();
                paragraphs.Add(newParagraph);
            }

            return paragraphs;
        }
        public int CompareTo(SortParagraph other)
        {

            int minSize = Math.Min(this.subParagraphs.Length, other.subParagraphs.Length);
            for (int i = 0; i < minSize; i++)
            {
                if (this.subParagraphs[i] != other.subParagraphs[i])
                {
                    if (this.subParagraphs[i] < other.subParagraphs[i])
                    {
                        return -1;
                    }
                    else
                    {
                        return 1;
                    }
                }
            }
            if (this.subParagraphs.Length == other.subParagraphs.Length)
            {
                return 0;
            }
            else
            {
                if (this.subParagraphs.Length < other.subParagraphs.Length)
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }
        }
    }



}

I marked jdweng's answer as correct, because I've got the missing hint. keyword "Icomparer". this solution now works fine, unless i dont need to remove any item (I dont need to, because Im goin to rebuild the complete list in case of removal)

class DuplicateKeyComparer<TKey>:IComparer<TKey> where TKey : IComparable
    {
        public int Compare(TKey x, TKey y)
        {
            int result = x.CompareTo(y);

            if (result == 0)
                return 1;   // Handle equality as beeing greater
            else
                return result;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM