2017-10-21 1 views
0

내 HTML 편집기를 구현하기 위해 treeview 구성 요소를 사용했습니다. 나는 자식 노드를 사용하여 A.C. 및 B.C.를 포함한 데이터 시간 문자열로 기록 이벤트를 기록했습니다. 시각. 내가 테스트 한 트리 뷰의 자식 노드 예제는 아래와 같습니다. 그것은 잘 때 자식 노드를 작동 Sorting child nodes of a treeview after populating the treeview in c# winformsA.D. 및 B.C.가 포함 된 자식 노드를 정렬합니다. 트리 뷰의 자식 노드에서 날짜 문자열을

using System.Collections; 
using System.Windows.Forms; 
namespace TreeViewEditor 
{ 
    public class NodeSorter : IComparer 
    { 
     public int Compare(object x, object y) 
     { 
       TreeNode tx = x as TreeNode; 
       TreeNode ty = y as TreeNode; 
       return string.Compare(tx.Text, ty.Text); 
      } 
    } 
} 

:

-History 
    ﹂ 0123/05/05 B.C. event001 
    ﹂ 2015/01/01 A.D. event002 
    ﹂ 2017/01/21 A.D. event003 
    ﹂ 2125/12/05 B.C. event000 

올바른 결과 정렬 후해야는 다음과 나는 다음과 같은 게시물 단지 simillar 코드를 사용

-History 
    ﹂ 2125/12/05 B.C. event000 
    ﹂ 0123/05/05 B.C. event001 
    ﹂ 2015/01/01 A.D. event002 
    ﹂ 2017/01/21 A.D. event003 

처럼 보인다 content AD 날짜 문자열 만. 자식 노드가 A.D.와 B.C.를 모두 처리 할 때 올바르게 정렬하는 방법을 알고 싶습니다. 트리 뷰에 날짜 시간 문자열.

+1

광고/BC 날짜의 데이터 유형은 무엇입니까? 짧고 관련있는 코드 스 니펫이 도움이 될 것입니다. 현재 사용중인 정렬 방식을 보여줍니다 (광고용으로 작동). –

+1

현재 (작동하지 않는)'IComparer '구현은 어떻게 생겼습니까? –

+3

올바르게 읽는다면 treeview 하위 노드와 관련이 없으며 AD 또는 BC 일 수있는 올바른 정렬 알고리즘과 관련이 있습니다. –

답변

1

이 작업을 수행하는 한 가지 방법은 날짜를 나타내는 클래스를 사용하고 클래스에 IComparable을 구현하는 것입니다. 이렇게하면 정렬 알고리즘을 사용자 정의하여 B.C. 날짜는 역순으로 (A.D. 날짜와 비교하여) 정렬됩니다.

아래 bool과 함께 bool을 사용하여 B.C.에 대해 false으로 설정된 클래스를 만들었습니다. 날짜. Parse() 메서드를 추가하여 예제 문자열 중 하나 ("이벤트"부분 제외) 중 하나를 가져와 BCADDate 개체를 반환 할 수 있습니다. 필요한 경우 "이벤트"속성과 문자열에서 이벤트를 구문 분석하는 기능을 추가하는 것은 간단합니다 (아래 주석 및 추가 가능). 날짜가 같은 BC/AD 지정 후 BC가없는 경우 일 다음 달 후, 수년에 비교하고, 그렇지 않으면 처음

  • 제공

    1. :

      은 기본적으로 비교처럼 작동 날들과 일치하지 않는 첫 번째 비교 결과를 반환합니다. 모든 속성은 내가 사용하는 데 도움이 경우도 IComparer 인터페이스의 구현을 추가

    편집

    일치하는 경우 -1

  • 반환 0 곱하여 BC 날짜에 대한 결과를 역방향 treeview와 함께. 여기
    class BCADDate : IComparable, IComparer 
    { 
        public int Year { get; set; } 
        public int Month { get; set; } 
        public int Day { get; set; } 
        public bool IsAD { get; set; } 
    
        public static BCADDate Parse(string input) 
        { 
         var result = new BCADDate(); 
    
         if (string.IsNullOrWhiteSpace(input)) 
          throw new ArgumentException("input cannot be null, empty, or whitespace"); 
    
         var dateADParts = input.Split(' '); 
         var dateParts = dateADParts[0].Split('/'); 
    
         if (dateParts.Length < 3) 
          throw new FormatException(
           "The string must have three parts separated by the '/' character."); 
    
         try 
         { 
          result.Year = int.Parse(dateParts[0]); 
          result.Month = int.Parse(dateParts[1]); 
          result.Day = int.Parse(dateParts[2]); 
         } 
         catch 
         { 
          throw new FormatException(
           "All parts of the date portion must be valid integers."); 
         } 
    
         result.IsAD = (dateADParts.Length == 1) 
          ? true // A.D. is true if nothing is specified 
          : dateADParts[1].IndexOf("A", StringComparison.OrdinalIgnoreCase) > -1; 
    
         return result; 
        } 
    
        public int CompareTo(object obj) 
        { 
         var other = obj as BCADDate; 
         if (other == null) return 1; 
    
         var BCMultiplier = IsAD ? 1 : -1; 
    
         // Use default comparers for our fields 
         if (this.IsAD != other.IsAD) 
          return this.IsAD.CompareTo(other.IsAD); 
         if (this.Year != other.Year) 
          return this.Year.CompareTo(other.Year) * BCMultiplier; 
         if (this.Month != other.Month) 
          return this.Month.CompareTo(other.Month) * BCMultiplier; 
         if (this.Day != other.Day) 
          return this.Day.CompareTo(other.Day) * BCMultiplier; 
    
         return 0; 
        } 
    
        public int Compare(object x, object y) 
        { 
         var first = x as BCADDate; 
         var second = y as BCADDate; 
    
         if (first == null) return second == null ? 0 : -1; 
         return first.CompareTo(second); 
        } 
    
        public override string ToString() 
        { 
         var bcad = IsAD ? "A.D." : "B.C."; 
         return $"{Year:0000}/{Month:00}/{Day:00} {bcad}"; 
        } 
    } 
    

    는 사용의 예 : 여기

    코드의

    var dates = new List<BCADDate> 
    { 
        BCADDate.Parse("0123/05/05 B.C."), 
        BCADDate.Parse("2015/01/01 A.D."), 
        BCADDate.Parse("2017/01/21 A.D."), 
        BCADDate.Parse("2125/12/05 B.C.") 
    }; 
    
    Console.WriteLine("Original ordering:"); 
    dates.ForEach(Console.WriteLine); 
    
    dates.Sort(); 
    Console.WriteLine("------------------"); 
    
    Console.WriteLine("Sorted ordering:"); 
    dates.ForEach(Console.WriteLine); 
    
    Console.Write("\nDone!\nPress any key to exit..."); 
    Console.ReadKey(); 
    

    출력 루퍼스 L의 솔루션을 기반으로

    enter image description here

  • +0

    @ Rufus L 귀하의 빠른 응답에 감사드립니다. 언젠가 당신을 투표 할 수 있기를 바랍니다. : D 귀하의 솔루션을 내 프로그램에 통합하고 성공할 때 피드백을드립니다. 다시 감사합니다. –

    0

    , 내가 구현 이 분류 기능을 TreeView 구성 요소. 놀랍습니다. TreeView의 NodeSorter에 대한 작은 수정을합니다. 루퍼스 L의 솔루션은 내 treeview 응용 프로그램에서 잘 작동합니다.

    수정 된 소스 코드는 다음과 같이 보여주고있다 : 내 응용 프로그램에서 사용

    using System; 
    using System.Collections; 
    using System.Windows.Forms; 
    namespace TreeViewEditor 
    { 
        class BCADDate : IComparable 
        { 
         public int Year { get; set; } 
         public int Month { get; set; } 
         public int Day { get; set; } 
         public bool IsAD { get; set; } 
    
         public static BCADDate Parse(string input) 
         { 
          var result = new BCADDate(); 
    
          if (string.IsNullOrWhiteSpace(input)) 
           throw new ArgumentException("input cannot be null, empty, or whitespace"); 
    
          var dateADParts = input.Split(' '); 
          var dateParts = dateADParts[0].Split('/'); 
    
          if (dateParts.Length < 3) 
           throw new FormatException(
            "The string must have three parts separated by the '/' character."); 
    
          try 
          { 
           result.Year = int.Parse(dateParts[0]); 
           result.Month = int.Parse(dateParts[1]); 
           result.Day = int.Parse(dateParts[2]); 
          } 
          catch 
          { 
           throw new FormatException(
            "All parts of the date portion must be valid integers."); 
          } 
    
          result.IsAD = (dateADParts.Length == 1) 
           ? true // A.D. is true if nothing is specified 
           : dateADParts[1].IndexOf("A", StringComparison.OrdinalIgnoreCase) > -1; 
    
          return result; 
         } 
    
         public int CompareTo(object obj) 
         { 
          var other = obj as BCADDate; 
          if (other == null) return 1; 
    
          var BCMultiplier = IsAD ? 1 : -1; 
    
          // Use default comparers for our fields 
          if (this.IsAD != other.IsAD) 
           return this.IsAD.CompareTo(other.IsAD); 
          if (this.Year != other.Year) 
           return this.Year.CompareTo(other.Year) * BCMultiplier; 
          if (this.Month != other.Month) 
           return this.Month.CompareTo(other.Month) * BCMultiplier; 
          if (this.Day != other.Day) 
           return this.Day.CompareTo(other.Day) * BCMultiplier; 
    
          return 0; 
         } 
        } 
    
        public class NodeSorter : IComparer 
        { 
         public int Compare(object x, object y) 
         { 
          TreeNode tx = x as TreeNode; 
          TreeNode ty = y as TreeNode; 
          BCADDate a = BCADDate.Parse(tx.Text); 
          BCADDate b = BCADDate.Parse(ty.Text); 
          return a.CompareTo(b); 
         } 
        } 
    } 
    

    코드를 다음과 같이 표시됩니다 :

    TreeView2.TreeViewNodeSorter = new NodeSorter(); 
    
    +0

    Rufus L의 기여도에 따라, 나는이 게시물에 대한 나의 수용 가능한 대답을 바꾸지 않을 것이다. 결승전에서 Rufus L에게 감사드립니다. –

    관련 문제