none
取得 listbox 陣列 RRS feed

  • 問題

  • form中建了一個 listbox 元件用來新增資料並印出,印出該筆資料後,listbox 會清空並繼續建立下一筆資料。

    目前想要一個類似儲存or復原的功能,記錄每一筆列印的資料,在操作過程中可以取得列印過的資料,並顯示回 listbox。

    但是在實做過程中遇到難題,試了好幾種方法,用listbox陣列儲存,最後都在撈出資料都卡在new()這個問題,查不到LISTBOX陣列的問題只好改方法 QQ。

    後來查到 ArrayList ,也卡在還原的部分,想求解。

       '全域變數
       Dim saveLB As New ArrayList() '儲存
       Dim Int As Integer = 0  '位置
    
        Private Sub BtnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnPrint.Click
            '列印
    	
    	'大量程式碼略
    	saveLB.add(me.listbox)
             Int =saveLB.Count
        End Sub
    
        Private Sub BtnLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnLast.Click
            '上一筆
    
            If saveLB.Count <= 0 Then Exit Sub
            Int -= 1
            If Int < 0 Then Exit Sub
    
            Me.listbox.clear() 'form元件 清除
    
            'Me.listbox.BeginUpdate()
    
            For i As Integer = 0 To saveLB(Int).items.count - 1
                Me.listbox.Items.Add(saveLB(Int).items.item(i))
            Next
    
            'Me.listbox.EndUpdate()
    
        End Sub
    目前卡在想將 已經存在變數中的listbox 還原顯示在 form 上的listbox 元件,

    已經存成功,但就是撈不出資料顯示在form上。QQ

    或是有什麼其他的方法可以使用


    • 已編輯 想不到ID 2019年9月14日 下午 10:07 補充
    2019年9月14日 下午 10:04

解答

  • 如果SaveLB存放的是ListBox, 可以將這一行:

    Dim saveLB As New ArrayList() '儲存

    改成

    Dim saveLB As New List(Of ListBox) '儲存

    執行以下的程式碼, 可以將SaveLB中儲存的第一個ListBox的內容還原到畫面上的ListBox, 以此類推:

    Me.listBox.DataSource=SaveLB(0).Items

    • 已標示為解答 想不到ID 2019年9月16日 下午 05:50
    2019年9月16日 上午 06:06
  • 不論你的 list 是 ArrayList 還是 List(of T),只要是用  list.Add(me.listbox) 加入,就一定是這個結果,因為不論你加了多少個進 list,實際上的 ListBox 物件還是只有一個。

    ListBox 是個參考型別,參考型別是可以讓一大堆變數同時指向同一個物件,你現在的狀況就是這樣。所以這件事情根本和你用 ArrayList 或 List(of T) 無關,而是在加進去的方式有關。

    我是比較傾向對於資料的操作和 UI 分離,所以我不會去存 ListBox,而只會存資料。

    至於 C# 轉 VB 你可以參考: https://dotblogs.azurewebsites.net/billchung/2018/10/12/130825


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/

    2019年9月16日 下午 11:58
    版主

所有回覆

  • 這樣做試看看:

    Me.listBox.DataSource=Nothing
    Me.listBox.DataSource=saveLB
    

    2019年9月14日 下午 10:30
  • 好像不行 。QQ

    saveLB 是用來儲記錄,列印一次就存一筆(listbox)進去。

    但撈資料時,只想從 saveLB 撈其中一筆,然後顯示在form的 listbox元件上。

    Me.listBox.DataSource=saveLB 會把所有記錄列出,

    下圖是我測試印了2筆資料,可以確定是印出2筆,但看不到內容 。

    想要達成的效果是

    2019年9月15日 上午 12:14
  • (1) 盡量使用 ListBox 的 DataSource 屬性指派資料,不要用 ListBox.Items.Add

    (2) 必須要創造出另外一個資料結構存放已經列印的資料,若有必要,可能會需要 Clone

    (3) 盡量使用 List<T> 等等泛型的集合,少用 ArrayList

    簡單的範例如下:

      public partial class Form1 : Form
        {
            // 原始資料
            private List<Person> _source;
    
            // 目前等待列印的索引 
            private int _currentIndex;
    
            // 繫結在 ListBox 的資料
            private List<Person> _listsource;
    
            // 已經列印的資料
            private List<Person> _printed;
    
            private bool _isReviewed;
    
    
            public Form1()
            {
                InitializeComponent();
                _currentIndex = -1;
                _isReviewed = false;
                CreateSource();
                _listsource = new List<Person>();
                _printed = new List<Person>();
                GetNextPrintData();
    
            }
    
            /// <summary>
            /// 取得下一個列印資料,並設定給 ListBox
            /// </summary>
            private void GetNextPrintData()
            {
                ResetListBox();
                _currentIndex++;
                _listsource.Add(_source[_currentIndex]);
                listBox1.DataSource = _listsource;
            }
    
    
            /// <summary>
            /// 取得已經列印的資料,並設定給 ListBox
            /// </summary>
            private void GetReviewData()
            {
                _currentIndex--;
                _isReviewed = false;
                ResetListBox();
                _listsource.AddRange(_printed);
                listBox1.DataSource = _listsource;
            }
    
    
    
            private void ResetListBox()
            {
                _listsource.Clear();
                listBox1.DataSource = null;
                listBox1.DisplayMember = "Name";
            }
    
    
            /// <summary>
            /// 建立原始資料
            /// </summary>
            private void CreateSource()
            {
                _source = new List<Person>();
    
                for (int i = 1; i < 100; i++)
                {
                    _source.Add(new Person { Name = $"person {i}", Age = i });
                }
    
    
            }
    
            private void printButton_Click(object sender, EventArgs e)
            {
                if (_isReviewed)
                {
                    GetNextPrintData();
                    _isReviewed = false;
                }
                label1.Text = $"假裝列印 {_listsource[0].Name} -- {_listsource[0].Age } ";
                _printed.Add(_listsource[0]);
                GetNextPrintData();
    
            }
    
            private void reviewButton_Click(object sender, EventArgs e)
            {
    
                label1.Text = "檢視已經列印的資料";
                GetReviewData();
                _isReviewed = true;
            }
        }
    
    
        public class Person
        {
            public string Name { get; set; }
    
            public int Age { get; set; }
        }


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/

    2019年9月15日 上午 07:33
    版主
  • 如果SaveLB存放的是ListBox, 可以將這一行:

    Dim saveLB As New ArrayList() '儲存

    改成

    Dim saveLB As New List(Of ListBox) '儲存

    執行以下的程式碼, 可以將SaveLB中儲存的第一個ListBox的內容還原到畫面上的ListBox, 以此類推:

    Me.listBox.DataSource=SaveLB(0).Items

    • 已標示為解答 想不到ID 2019年9月16日 下午 05:50
    2019年9月16日 上午 06:06
  • Bill 大大的方式超出我能力範圍,c# 的程式碼有些不懂,查了又弄一整天還沒搞出來,要等連假比較有空才能研究。

    弄到程式碼好像被我改壞了,tihs大大的方式還一度顯示不出來,但開新專案測試,確實是我想顯示的結果沒錯。

    這步驟花了我三天,真的非常感謝兩位。

    2019年9月16日 下午 06:01
  • 我又遇到另一個問題,在我將 listbox 存進 saveLB 之後,

    將 listbox 清除,saveLB 裡面的也一併被清除了,導致撈不到資料。

    有查到被清空的原因,但是查不到該怎麼直接複製一個出來。 Clone 不知道該怎麼使用在LISTBOX  。QQ

    2019年9月16日 下午 09:33
  • 不論你的 list 是 ArrayList 還是 List(of T),只要是用  list.Add(me.listbox) 加入,就一定是這個結果,因為不論你加了多少個進 list,實際上的 ListBox 物件還是只有一個。

    ListBox 是個參考型別,參考型別是可以讓一大堆變數同時指向同一個物件,你現在的狀況就是這樣。所以這件事情根本和你用 ArrayList 或 List(of T) 無關,而是在加進去的方式有關。

    我是比較傾向對於資料的操作和 UI 分離,所以我不會去存 ListBox,而只會存資料。

    至於 C# 轉 VB 你可以參考: https://dotblogs.azurewebsites.net/billchung/2018/10/12/130825


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/

    2019年9月16日 下午 11:58
    版主