5月 18, 2024

[C#] ComboBox 透過 ObservableCollection 同步更新資料

今天恰好有個機會寫一個串接功能型的 Form Application,其中當然不乏撈資料的功能,然後產出一個下拉列表 (ComboBox)

但是資料集這種東西也不一定是固定的,可能會依照需求的參數不同而會有不同的結果,因此可能會頻繁的改變內容,然後同時間要改變畫面的選項列表

這時當然最簡單的方法是寫一個 function ,傳入列表資料後,針對畫面上的內容跑迴圈重新塞進去,但這樣的方法對我來說有個小風險,就是如果在資料改變的地方忘記呼叫方法,那就算拿到了新資料也不會同步

於是乎,就 Google 了一下,找到了關於 ObservableCollection 的用法 ...

ObservableCollection 顧名思義就是一個可觀察的集合,而他的觀察對象可以自行定義,例如我目標用於 ComboBox 中資料是 DataSource,也就是下拉列表的項目,對我而言就是一個字串陣列

而下拉選項改變的時機就是當 ObservableCollection 的資料改變時,他也提供了 CollectionChanged 的事件來觸發


因此把這些東西集合在一起後就可以簡單寫一個範例


    public ObservableCollection<KeyValuePair<string, Bags.ApiResp.Items>> list_items = [];
public BindingSource bs_items = new BindingSource();

private void Form1_Load(object sender, EventArgs e)
{
        select_Item.DataSource = bs_items;
list_items.CollectionChanged += List_items_CollectionChanged;
}

private void List_items_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
bs_items.DataSource = list_items.Select(kvp => kvp.Key).ToList();
}

一開始預設了一個 BindingSource bs_items 是要將下拉列表的資料來源連結(繫結) 在該變數上,才能在變數資料改變時下拉列表同時變化

接著最重要的主角 list_items 事先綁定一個 CollectionChanged 事件,這個事件執行的目的就是為了改變 bs_items 的資料內容

如此一來,當我們在程式中的任何一個地方,取得新的下拉列表的資料後,對 list_items 做資料更新時,他就會觸發 Change 事件,進而將列表的資料一併更新了


*注1. 上述寫法不一定是最正確的用法,但我自己執行後的結果是正確的所以拿出來當範例
*注2. Collection 的 <T> 是看自己需求寫就好,屬性不是一定,我寫 KeyValuePair 是其他功能取資料需要
*注3. 如果資料量大的時候,要注意不要直接操作 list_items 的內容,先處理好資料集後再取代內容,避免效能問題




寫太久了腦袋有點花,感覺越寫越亂,就當作這是以後遇到時回來回憶的筆記吧 ..

沒有留言:

張貼留言