Từ 1 tới 6 trên tổng số 6 kết quả

Đề tài: Cách lập trình tập hợp cho dữ liệu đã duyệt trong C#?

  1. #1
    Ngày gia nhập
    09 2008
    Nơi ở
    Ở nhà chứ đâu... nhìn cái gì?!?!
    Bài viết
    218

    Thumbs down Cách lập trình tập hợp cho dữ liệu đã duyệt trong C#?

    Chào các anh chị, các bạn,

    Hiện tôi đang làm một chương trình mô phỏng theo TotalCommander nhưng code trên C#. Tôi đang phân vân về việc xây dựng một cơ chế có thể lưu lại 'history of folder-path' mà tôi đã duyệt qua.

    Ví dụ tôi muốn tập hợp này gồm 32 chỗ chứa, mỗi lần duyệt qua một đường dẫn thư mục (nếu OK) thì tập hợp này sẽ add đường dẫn vừa duyệt. Đến một lúc nào đó khi tôi duyệt hết 32 lần thì tập hợp này sẽ tự remove phần tử đầu tiên và sẽ add tiếp một phần tử mới vào cuối tập hợp khi duyệt tiếp (con trỏ luôn trỏ tới phần tử cuối trong tập hợp).

    Chương trình của tôi sẽ có 2 nút 'Next' và 'Previous' để thao tác với tập hợp này (2 nút này sẽ ẩn hiện ứng với vị trí đang trỏ tới trong tập hợp).

    Các anh chị, các bạn có thể đề xuất cho tôi một hướng làm được không? Nếu anh chị, các bạn không chê cười và muốn góp sức thực hiện project này có thể cho tôi địa chị mail và tôi sẽ invite các anh chị vào SVN host project này tại Assembla.com

    Cám ơn rất nhiều

  2. #2
    Ngày gia nhập
    02 2008
    Bài viết
    88

    Bạn nghiên cứu lớp List<>
    nó có đủ các phương thức như add, insert, delete... để giúp bạn làm cái tập hợp đó dễ dàng
    Ví dụ
    Visual C# Code:
    1. List<string> list = new List<string> ();
    2. list.Add("1");
    3. list.Add("2");
    4. list.Add("3");
    5. list.Add("4");
    6. ........
    Mình từ Caulacbovb qua)
    Giã từ VB6 đến với VB.Net, C# và Java.

  3. #3
    Ngày gia nhập
    09 2008
    Nơi ở
    Ở nhà chứ đâu... nhìn cái gì?!?!
    Bài viết
    218

    Trích dẫn Nguyên bản được gửi bởi anhtuyenbk Xem bài viết
    Bạn nghiên cứu lớp List<>
    nó có đủ các phương thức như add, insert, delete... để giúp bạn làm cái tập hợp đó dễ dàng
    Ví dụ
    Visual C# Code:
    1. List<string> list = new List<string> ();
    2. list.Add("1");
    3. list.Add("2");
    4. list.Add("3");
    5. list.Add("4");
    6. ........
    Cám ơn bạn rất nhiều, mình đã tìm hiểu kể cả Stack và Queue trước đó rồi. Lớp List<T> mình muốn tập hợp của mình có một Capacity nhất định = 32, trong khi List sẽ tự tăng không gian chứa có nghĩa nó cũng không tự remove phần tử đầu tiên.

    Theo ý mình nên viết một tập hợp gần như LinkedList và Queue. Cũng đang tìm tòi nhiều...

    Nếu bài viết của mình có khó hiểu thì xin các bạn hãy liên tưởng tới cách hoạt động của 2 nút 'Next' và 'Previous' trên trình duyệt web.

    Cám ơn

  4. #4
    Ngày gia nhập
    09 2008
    Nơi ở
    Ở nhà chứ đâu... nhìn cái gì?!?!
    Bài viết
    218

    Mặc định Kết quả sau 1 ngày và 1 đêm nghiên cứu

    Phù, rốt cuộc cũng có thể làm được một số yêu cầu về cái tập hợp này. Sau đây mình xin phép được share code nếu có bạn nào cần.

    Trước hết tập hợp này gần giống như Queue, vì nó sẽ có một không gian chứa nhất định và không tự gia tăng kích thước khi đầy.

    Visual C# Code:
    1. /// <summary>
    2.     ///
    3.     /// Represent a FIFO collection of object. It have a specified capacity and
    4.     /// will automatically remove its element when out of container-space.
    5.     ///
    6.     /// This class cannot be inherited.
    7.     ///
    8.     /// </summary>
    9.     ///
    10.     /// <typeparam name="T">Type-Generic</typeparam>
    11.     public sealed class HistoryQueue<T> : IEnumerable<T>
    12.     {
    13.         private T[] mContainerSpace;
    14.  
    15.         private const int DEFAULT_CAPACITY = 5;
    16.  
    17.         private int mSize;
    18.  
    19.         private int iHead, iTail;
    20.  
    21.         /// <summary>
    22.         ///
    23.         /// Constructor for a new <code>HistoryQueue<T></code>.
    24.         ///
    25.         /// </summary>
    26.         public HistoryQueue()
    27.         {
    28.             mContainerSpace = new T[DEFAULT_CAPACITY];
    29.  
    30.             mSize = iHead = iTail = 0;
    31.         }
    32.  
    33.         /// <summary>
    34.         ///
    35.         /// If the <code>HistoryQueue</code> is full, it will automatically remove the first element,
    36.         /// and then add the new element.
    37.         ///
    38.         /// </summary>
    39.         ///
    40.         /// <param name="element">New element</param>
    41.         public void Enqueue(T element)
    42.         {
    43.             // Size is full...
    44.             if (IsFull())
    45.             {
    46.                 Dequeue(); // Removes the first element.
    47.  
    48.                 NormalEnqueue(element); // Adds new element then.
    49.             }
    50.             else
    51.                 NormalEnqueue(element);
    52.         }
    53.  
    54.         /// <summary>
    55.         ///
    56.         /// Adds a new element to the last place of <code>HistoryQueue</code> normally.
    57.         ///
    58.         /// </summary>
    59.         ///
    60.         /// <param name="element">New element</param>
    61.         private void NormalEnqueue(T element)
    62.         {
    63.             mContainerSpace[iTail] = element;
    64.  
    65.             iTail = (iTail + 1) % mContainerSpace.Length;
    66.  
    67.             mSize++;
    68.         }
    69.  
    70.         /// <summary>
    71.         ///
    72.         /// Removes element at the first place in <code>HistoryQueue</code>.
    73.         ///
    74.         /// </summary>
    75.         public void Dequeue()
    76.         {
    77.             // Queue is empty...
    78.             if (IsEmpty())
    79.                 throw new InvalidOperationException("Cannot dequeue when there is no element in queue.");
    80.  
    81.             mContainerSpace[iHead] = default(T);
    82.  
    83.             iHead = (iHead + 1) % mContainerSpace.Length;
    84.  
    85.             mSize--;
    86.         }
    87.  
    88.         /// <summary>
    89.         ///
    90.         /// Clears all element in <code>HistoryQueue</code>.
    91.         ///
    92.         /// </summary>
    93.         public void Clear()
    94.         {
    95.             if (iHead < iTail)
    96.                 Array.Clear(mContainerSpace, iHead, mSize);
    97.             else
    98.             {
    99.                 Array.Clear(mContainerSpace, iHead, mContainerSpace.Length - iHead);
    100.                 Array.Clear(mContainerSpace, 0, iTail);
    101.             }
    102.             mSize = iHead = iTail = 0;
    103.         }
    104.  
    105.         /// <summary>
    106.         ///
    107.         /// Check if the <code>HistoryQueue</code> is full.
    108.         ///
    109.         /// </summary>
    110.         ///
    111.         /// <returns><code>true</code> if the <code>HistoryQueue</code> is full; otherwise <code>false</code>.</returns>
    112.         public bool IsFull()
    113.         {
    114.             return mSize == mContainerSpace.Length;
    115.         }
    116.  
    117.         /// <summary>
    118.         ///
    119.         /// Check if the <code>HistoryQueue</code> is empty.
    120.         ///
    121.         /// </summary>
    122.         ///
    123.         /// <returns><code>true</code> if the <code>HistoryQueue</code> is full; otherwise <code>false</code>.</returns>
    124.         public bool IsEmpty()
    125.         {
    126.             return mSize == 0;
    127.         }
    128. ...
    129. // Code for IEnumerator<T> comming soon...

    Trước đây mình cũng đã làm việc nhiều với lập trình Generic bên Java và biết qua Interface là Iterator dùng để duyệt tập hợp. Mình cũng tìm hiểu được một Interface tương tự như trong C# đó là IEnumerator<T> mình cũng đã viết và demo thử cho HistoryQueue thành công, tuy nhiên mình cần sửa chữa lại một tí và sẽ post trong thời gian ngắn nhất (do mình muốn khi duyệt qua HistoryQueue thì duyệt từ cuối đến đầu theo yêu cầu bài toán của mình - con trỏ lun trỏ tới phần tử cuối).

  5. #5
    Ngày gia nhập
    09 2008
    Nơi ở
    Ở nhà chứ đâu... nhìn cái gì?!?!
    Bài viết
    218

    Mặc định Test tập hợp cho dữ liệu đã duyệt

    Chào các bạn,

    Mình đã hoàn thành phần Enumerator cho duyệt dữ liệu, và test vấn đề của mình. Nhưng đã có một vài vấn đề nảy sinh như sau:

    Trước hết minh xin tóm tắt lại
    + Mình muốn có một navigator giống như 2 nút Next và Previous trên trình duyệt web hoặc giống như cơ chế Undo và Redo, nhưng những Collection trong .NET theo mình nghĩ chưa hỗ trợ được cho bài toán của mình. Collection mình cần là sẽ Add phần tử vào đầu danh sách, khi đã đầy thì sẽ tự xóa phần tử ở cuối và add tiếp vào đầu.

    + Để làm một cơ chế Navigator thì phải cần tới 2 Collection như vậy. Khi muốn duyệt ngược (undo) về một phần tử thì sẽ Peek phần tử đầu trong danh sách 1 và add nó vào danh sách 2. Như vậy phương thức Peek sẽ lấy và remove phần tử đầu tiên trong collection. Khi muốn duyệt tới phần tử trước đó (redo) thì sẽ Peek phần tử đầu trong danh sách 2 và add nó lại vào danh sách 1. Và trong phương thức Peek của mình đã xảy ra một số vấn đề. Mình xin đưa code sau để các bạn tham khảo và nếu có thể phát hiện và giúp mình thì mình rất trân trọng.

    Trước hết là về Code cho Collection:

    Visual C# Code:
    1. using System;
    2. using System.Collections.Generic;
    3.  
    4. namespace SharpCodeHunter.SharpCommander.Data
    5. {
    6.     /// <summary>
    7.     ///
    8.     /// An <code>Interface</code> to build a history-factory.
    9.     ///
    10.     /// </summary>
    11.     public interface IHistoryFactory<T>
    12.     {
    13.         /// <summary>
    14.         ///
    15.         /// Checks if there is more next element to point.
    16.         ///
    17.         /// </summary>
    18.         ///
    19.         /// <returns><c>true</c> if there is still more next element; otherwise <c>false</c>.</returns>
    20.         bool HasNext();
    21.        
    22.         /// <summary>
    23.         ///
    24.         /// Moves to the next element.
    25.         ///
    26.         /// </summary>
    27.         ///
    28.         /// <returns>Next element.</returns>
    29.         T MoveNext();
    30.        
    31.         /// <summary>
    32.         ///
    33.         /// Sets the pointer to its first initializing position.
    34.         ///
    35.         /// </summary>
    36.         void Reset();
    37.     }
    38. }

    Visual C# Code:
    1. using System;
    2.  
    3. namespace SharpCodeHunter.SharpCommander.Data
    4. {
    5.     /// <summary>
    6.     ///
    7.     /// Represents a FIFO collection of object. It has a specified capacity and
    8.     /// will automatically remove its element when out of container-space.
    9.     ///
    10.     /// This class cannot be inherited.
    11.     ///
    12.     /// </summary>
    13.     ///
    14.     /// <author>O'Wicked Fox</author>
    15.     ///
    16.     /// <typeparam name="T">Type-Generic</typeparam>
    17.     public sealed class HistoryQueue<T>
    18.     {
    19.         #region --- field(s) ---
    20.        
    21.         private T[] mContainerSpace;
    22.  
    23.         private const int DEFAULT_CAPACITY = 5;
    24.  
    25.         private int mSize;
    26.  
    27.         private int iHead, iTail;
    28.        
    29.         #endregion
    30.        
    31.         #region --- constructor(s) ---
    32.        
    33.         /// <summary>
    34.         ///
    35.         /// Constructs a new <code>HistoryQueue<T></code>.
    36.         ///
    37.         /// </summary>
    38.         public HistoryQueue()
    39.         {
    40.             mContainerSpace = new T[DEFAULT_CAPACITY];
    41.  
    42.             mSize = iHead = iTail = 0;
    43.         }
    44.        
    45.         #endregion
    46.  
    47.         #region --- method(s) ---
    48.  
    49.         /// <summary>
    50.         ///
    51.         /// If the <c>HistoryQueue</c> is full, it will automatically dequeue the first element,
    52.         /// and then enqueue the new element.
    53.         ///
    54.         /// </summary>
    55.         ///
    56.         /// <param name="element">New element.</param>
    57.         public void Enqueue(T element)
    58.         {
    59.             // Size is full...
    60.             if (IsFull)
    61.             {
    62.                 Dequeue(); // Dequeues the first element.
    63.  
    64.                 NormalEnqueue(element); // Enqueues new element then.
    65.             }
    66.             else
    67.                 NormalEnqueue(element);
    68.         }
    69.  
    70.         /// <summary>
    71.         ///
    72.         /// Enqueues a new element to the tail-index of <c>HistoryQueue</c> normally.
    73.         ///
    74.         /// </summary>
    75.         ///
    76.         /// <param name="element">New element.</param>
    77.         private void NormalEnqueue(T element)
    78.         {
    79.             mContainerSpace[iTail] = element;
    80.  
    81.             iTail = (iTail + 1) % mContainerSpace.Length;
    82.  
    83.             mSize++;
    84.         }
    85.  
    86.         /// <summary>
    87.         ///
    88.         /// Dequeues element at head-index in <c>HistoryQueue</c>.
    89.         ///
    90.         /// </summary>
    91.         ///
    92.         ///<returns></returns>
    93.         public void Dequeue()
    94.         {
    95.             // Queue is empty...
    96.             if (IsEmpty)
    97.                 throw new InvalidOperationException("Cannot dequeue when there is no element in queue.");
    98.  
    99.             // Dequeues at head-index.
    100.             mContainerSpace[iHead] = default(T);
    101.  
    102.             iHead = (iHead + 1) % mContainerSpace.Length;
    103.  
    104.             mSize--;
    105.         }
    106.        
    107.         /// <summary>
    108.         ///
    109.         /// Dequeues element at tail-index in <c>HistoryQueue</c>.
    110.         ///
    111.         /// </summary>
    112.         ///
    113.         /// <returns></returns>
    114.         public T Peek()
    115.         {
    116.             // Queue is empty...
    117.             if (IsEmpty)
    118.                 throw new InvalidOperationException("Cannot peek when there is no element in queue.");
    119.            
    120.             T peekingOne = default(T);
    121.            
    122.             // Dequeues at tail-index.
    123. //          if (iTail == 0)
    124. //          {
    125. //              iTail = mSize;
    126. //
    127. //              T peekingOne = mContainerSpace[iTail -1];
    128. //
    129. //              //mContainerSpace[iTail] = default(T);
    130. //
    131. //              iTail = (iTail - 1) % mContainerSpace.Length;
    132. //
    133. //              //mContainerSpace[iTail] = default(T);
    134. //
    135. //              mSize--;
    136. //
    137. //              return peekingOne;
    138. //          }
    139. //          else if (iTail < 0) {
    140. //              iTail = Math.Abs(1 - mSize);
    141. //
    142. //              T peekingOne = mContainerSpace[iTail];
    143. //
    144. //              iTail = (iTail) % mContainerSpace.Length;
    145. //
    146. //              mSize--;
    147. //
    148. //              return peekingOne;
    149. //          }
    150.            
    151.             if (iTail % mSize == 0)
    152.             {
    153.                 if (iTail == 0)
    154.                 {
    155.                     iTail = mSize - 1;
    156.                    
    157.                     peekingOne = mContainerSpace[iTail];
    158.                    
    159.                     mContainerSpace[iTail] = default(T);
    160.                    
    161.                     iTail = iTail % mContainerSpace.Length;
    162.                    
    163.                     mSize--;
    164.                 }
    165.                 else
    166.                 {
    167.                     peekingOne = mContainerSpace[iTail - 1];
    168.                    
    169.                     mContainerSpace[iTail] = default(T);
    170.                    
    171.                     iTail = (iTail - 1) % mContainerSpace.Length;
    172.                    
    173.                     mSize--;
    174.                 }
    175.                
    176.                 //return peekingOne;
    177.             }
    178.             else
    179.             {
    180.                 if (iTail == mContainerSpace.Length)
    181.                 {
    182.                     peekingOne = mContainerSpace[iTail - 1];
    183.                    
    184.                     mContainerSpace[iTail - 1] = default(T);
    185.                    
    186.                     iTail = mContainerSpace.Length;
    187.                    
    188.                     mSize--;
    189.                 }
    190.                 else
    191.                 {
    192.                     peekingOne = mContainerSpace[iTail - 1];
    193.                    
    194.                     mContainerSpace[iTail - 1] = default(T);
    195.                     //mSize--;
    196.                    
    197.                     //mContainerSpace[iTail] = default(T);
    198.                    
    199.                     //iTail = mSize - iTail;
    200.                    
    201.                     mSize--;
    202.                    
    203.                     iTail = mContainerSpace.Length;
    204.                 }
    205.             }
    206.            
    207.             return peekingOne;
    208.         }
    209.  
    210.         /// <summary>
    211.         ///
    212.         /// Dismisses all element(s) in <c>HistoryQueue</c>.
    213.         ///
    214.         /// </summary>
    215.         public void Clear()
    216.         {
    217.             if (iHead < iTail)
    218.                 Array.Clear(mContainerSpace, iHead, mSize);
    219.             else
    220.             {
    221.                 Array.Clear(mContainerSpace, iHead, mContainerSpace.Length - iHead);
    222.                 Array.Clear(mContainerSpace, 0, iTail);
    223.             }
    224.  
    225.             mSize = iHead = iTail = 0;
    226.         }
    227.        
    228.         /// <summary>
    229.         ///
    230.         /// Gets a Type-Generic object by its index.
    231.         ///
    232.         /// </summary>
    233.         ///
    234.         /// <param name="index">Type-Generic object's index number.</param>
    235.         ///
    236.         /// <returns>Type-Generic element.</returns>
    237.         internal T GetElement(int index)
    238.         {
    239.             return mContainerSpace[(iHead + index) % mContainerSpace.Length];
    240.         }
    241.  
    242.         /// <summary>
    243.         ///
    244.         /// Enumerates each element in <c>HistoryQueue</c> from tail to head.
    245.         ///
    246.         /// </summary>
    247.         ///
    248.         /// <returns></returns>
    249.         public IHistoryFactory<T> Enumerate()
    250.         {
    251.             return new HistoryFactory((HistoryQueue<T>)this);
    252.         }
    253.  
    254.         #endregion
    255.        
    256.         #region --- property(es) ---
    257.        
    258.         public int Count
    259.         {
    260.             get { return mSize; }
    261.         }
    262.        
    263.         /// <summary>
    264.         ///
    265.         /// Checks if the <c>HistoryQueue</c> is full.
    266.         ///
    267.         /// </summary>
    268.         ///
    269.         /// <returns><code>true</code> if the <code>HistoryQueue</code> is full; otherwise <code>false</code>.</returns>
    270.         public bool IsFull
    271.         {
    272.             get { return mSize == mContainerSpace.Length; }
    273.         }
    274.  
    275.         /// <summary>
    276.         ///
    277.         /// Checks if the <code>HistoryQueue</code> is empty.
    278.         ///
    279.         /// </summary>
    280.         ///
    281.         /// <returns><code>true</code> if the <code>HistoryQueue</code> is full; otherwise <code>false</code>.</returns>
    282.         public bool IsEmpty
    283.         {
    284.             get { return mSize == 0; }
    285.         }
    286.        
    287.         #endregion
    288.        
    289.         #region --- nested struct(s) ---
    290.        
    291.         /// <summary>
    292.         ///
    293.         /// Represents a history engine.
    294.         ///
    295.         /// </summary>
    296.         public struct HistoryFactory : IHistoryFactory<T>, IDisposable
    297.         {
    298.             #region --- fiend(s) ---
    299.            
    300.             private HistoryQueue<T> mQueue;
    301.  
    302.             private int mIndex;
    303.  
    304.             private T mCurrent;
    305.  
    306.             #endregion
    307.            
    308.             #region --- constructor(s) ---
    309.            
    310.             /// <summary>
    311.             ///
    312.             ///
    313.             ///
    314.             /// </summary>
    315.             ///
    316.             /// <param name="queue"></param>
    317.             internal HistoryFactory(HistoryQueue<T> queue)
    318.             {
    319.                 mQueue = queue;
    320.  
    321.                 mIndex = mQueue.mSize;
    322.  
    323.                 mCurrent = default(T);
    324.             }
    325.            
    326.             #endregion
    327.  
    328.             #region --- implements IHistoryIterator<T> ---
    329.  
    330.             public bool HasNext()
    331.             {
    332.                 if (mIndex == -2) return false;
    333.  
    334.                 --mIndex;
    335.  
    336.                 if (mIndex < 0)
    337.                 {
    338.                     mIndex = -2;
    339.                     mCurrent = default(T);
    340.                     return false;
    341.                 }
    342.                
    343.                 return true;
    344.             }
    345.            
    346.             public T MoveNext()
    347.             {
    348.                 mCurrent = mQueue.GetElement(mIndex);
    349.                
    350.                 return mCurrent;
    351.             }
    352.            
    353.             public void Reset()
    354.             {
    355.                 mIndex = -1;
    356.  
    357.                 mCurrent = default(T);
    358.             }
    359.  
    360.             public T Current
    361.             {
    362.                 get
    363.                 {
    364.                     if (mIndex < 0)
    365.                     {
    366.                         if (mIndex == -1)
    367.                             throw new InvalidOperationException("HistoryEnumerator is not started.");
    368.                         else
    369.                             throw new InvalidOperationException("HistoryEnumerator is ended.");
    370.                     }
    371.  
    372.                     return mCurrent;
    373.                 }
    374.             }
    375.            
    376.             #endregion
    377.  
    378.             #region --- implements IDisposable ---
    379.  
    380.             public void Dispose()
    381.             {
    382.                 mIndex = -2;
    383.  
    384.                 mCurrent = default(T);
    385.             }
    386.  
    387.             #endregion
    388.         }
    389.        
    390.         #endregion
    391.     }
    392. }

    Code cho form Demo

    Visual C# Code:
    1. using System;
    2. using System.Drawing;
    3. using System.Windows.Forms;
    4.  
    5. using SharpCodeHunter.SharpCommander.Data;
    6.  
    7. namespace SharpCodeHunter.SharpCommander.Test
    8. {
    9.     /// <summary>
    10.     /// Description of FormHistoryQueueDemo.
    11.     /// </summary>
    12.     public partial class FormHistoryQueueDemo : Form
    13.     {
    14.         HistoryQueue<string> queue = new HistoryQueue<string>();
    15.         HistoryQueue<string> temp = new HistoryQueue<string>();
    16.        
    17.         public FormHistoryQueueDemo()
    18.         {
    19.             InitializeComponent();
    20.         }
    21.        
    22.         void ButtonEnqueueClick(object sender, EventArgs e)
    23.         {
    24.             queue.Enqueue(textboxElement.Text);
    25.            
    26.             labelElement.Text = textboxElement.Text;
    27.            
    28.             textboxElement.Clear();
    29.             textboxElement.Focus();
    30.            
    31.             this.RefreshContainerSpace();
    32.         }
    33.        
    34.         void ButtonExitClick(object sender, EventArgs e)
    35.         {
    36.             this.Close();
    37.            
    38.             this.RefreshContainerSpace();
    39.         }
    40.        
    41.         void MenuitemDequeueClick(object sender, EventArgs e)
    42.         {
    43.             queue.Dequeue();
    44.            
    45.             this.RefreshContainerSpace();
    46.         }
    47.        
    48.         void MenuitemClearAllClick(object sender, EventArgs e)
    49.         {
    50.             queue.Clear();
    51.            
    52.             this.RefreshContainerSpace();
    53.         }
    54.        
    55.         private void RefreshContainerSpace() {
    56.             listviewContainerSpace.Clear();
    57.             listviewTemp.Clear();
    58.            
    59.             IHistoryFactory<string> history = queue.Enumerate();
    60.             while (history.HasNext()) {
    61.                 ListViewItem item = new ListViewItem();
    62.                 item.Text=history.MoveNext();
    63.                 item.ImageIndex = 0;
    64.                
    65.                 listviewContainerSpace.Items.Add(item);
    66.             }
    67.            
    68.             IHistoryFactory<string> temphistory = temp.Enumerate();
    69.             while (temphistory.HasNext()) {
    70.                 ListViewItem item = new ListViewItem();
    71.                 item.Text=temphistory.MoveNext();
    72.                 item.ImageIndex = 0;
    73.                
    74.                 listviewTemp.Items.Add(item);
    75.             }
    76.            
    77.             if (listviewContainerSpace.Items.Count == 0 && listviewTemp.Items.Count == 0) {
    78.                 buttonPrevious.Enabled = false;
    79.                 buttonNext.Enabled = false;
    80.             }
    81.             else if (listviewContainerSpace.Items.Count == 0 && listviewTemp.Items.Count > 0) {
    82.                 buttonPrevious.Enabled = false;
    83.                 buttonNext.Enabled = true;
    84.             }
    85.             else if (listviewContainerSpace.Items.Count > 0 && listviewTemp.Items.Count == 0) {
    86.                 buttonNext.Enabled = false;
    87.                 buttonPrevious.Enabled = true;
    88.             }
    89.             else {
    90.                 buttonNext.Enabled = true;
    91.                 buttonPrevious.Enabled = true;
    92.             }
    93.         }
    94.        
    95.         void ButtonNextClick(object sender, EventArgs e)
    96.         {
    97.             string peeknext = temp.Peek();
    98.             queue.Enqueue(peeknext);
    99.            
    100.             this.RefreshContainerSpace();
    101.            
    102.             labelElement.Text = peeknext;
    103.         }
    104.        
    105.         void ButtonPreviousClick(object sender, EventArgs e)
    106.         {
    107.             string peekpre = queue.Peek();
    108.             temp.Enqueue(peekpre);
    109.            
    110.             this.RefreshContainerSpace();
    111.            
    112.             labelElement.Text = peekpre;
    113.         }
    114.     }
    115. }
    Các bạn có thể xây dự giao diện như hình sau:

    Các bạn thử Enqueue khoãng 8 phần tử sẽ thấy lỗi khi duyệt do iTail chưa sử lý kỹ. Tôi cũng đang cố gắng.

  6. #6
    Ngày gia nhập
    09 2008
    Nơi ở
    Ở nhà chứ đâu... nhìn cái gì?!?!
    Bài viết
    218

    Red face Cách lập trình tập hợp cho dữ liệu đã duyệt trong C#?

    Chào các bạn, mình vừa tìm được 1 project có thể giúp mình làm được bài này rùi (codeproject). Các bạn có thể tham khảo link dưới đây:

    Code:
    http://www.codeproject.com/KB/cs/generic_undo_redo.aspx
    Cũng có những điều hay đáng học trong bài viết này.

    Cheer!

Các đề tài tương tự

  1. Trình duyệt Opera, giúp bạn trải nghiệm tốt hơn khi duyệt wap
    Gửi bởi hailuacuibep trong diễn đàn Software (Phần mềm) | Ebooks
    Trả lời: 2
    Bài viết cuối: 02-01-2013, 12:12 PM
  2. Lỗi con trỏ DSLK, add vào nhưng khi duyệt con trỏ vẫn bằng NULL, ko duyệt được
    Gửi bởi kuhoang0512 trong diễn đàn Thảo luận, góp ý code C/C++ của bạn
    Trả lời: 9
    Bài viết cuối: 29-11-2011, 04:20 PM
  3. Duyệt các controls bằng foreach thì control nào sẽ được duyệt trước
    Gửi bởi chitviv trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 4
    Bài viết cuối: 05-10-2011, 10:01 PM
  4. Cách thức duyệt tiền tự trên cây khi duyệt từ con trái nhất rồi sang anh em ruột phải?
    Gửi bởi tyrant trong diễn đàn Thắc mắc CTDL & Giải thuật
    Trả lời: 0
    Bài viết cuối: 14-09-2011, 10:53 AM
  5. ADO.NET Thứ tự của control( textbox) được duyệt khi chạy đệ quy duyệt các control trên form
    Gửi bởi caheoxanh trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 3
    Bài viết cuối: 17-06-2011, 09:12 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn