在 WinForm 的 ComboBox 元件中分別處理欲顯示的文字以及其實際值

基本用法

Windows Form 中的 ComboBox 也就是下拉式選單,最簡單的用法就是直接在裡面放入一堆字串。例如我們在一個空白表單上有一個叫做 comboBox1 的元件。

可以利用以下程式簡單完成,示範的程式直接放入視窗的建構函式之中,這樣當視窗開啟時就會有三個選項。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        // add 3 items to comboBox
        comboBox1.Items.Add("Apple");
        comboBox1.Items.Add("Banana");
        comboBox1.Items.Add("Orange");
    }
} 

如此一來,在取值的時候,就可以利用 SelectedItem 的屬性來得到所選擇的字串。新增一個 SelectedIndexChanged 的事件,當發生時將選擇的值放入文字框 textBox1 中。

private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    // remember cast to a string type
    textBox1.Text = (string)comboBox1.SelectedItem;
} 

客製化項目

不過有時候案情並不單純,所以我們就想要顯示的文字長不一樣,這樣既方便使用者選擇又美觀,而不是把原始的資料直接秀在選單裡,這時候就可以自己建一個 struct 結構來放入 ComboBox 之中,這樣會很方便。

ComboBox 原本的設計就是可以放入任何資料型態的資料。

首先來設計一個結構,這裡的重點是利用 override 關鍵字取代原生的 ToString 方法,這樣才可以顯示我們想要顯示的字串。

struct MyItem
{
    public MyItem(string displayName, string realValue)
    {
        DisplayName = displayName;
        RealValue = realValue;
    }
    public string DisplayName { get; set; }
    public string RealValue { get; set; }
    // must have this override method to display the right string.
    public override string ToString()
    {
        return DisplayName;
    }
} 

發現很少人寫到 C++/CLI 的版本,所以這邊補上對應的寫法。這邊我們必須自定一個 Class 才會繼承到 Object 物件。

public ref class MyItem
{
    public: MyItem(System::String^ displayName, System::String^ realValue)
    {
        this->DisplayName = displayName;
        this->RealValue = realValue;
    }
    private: System::String^ DisplayName;
    private: System::String^ RealValue;
    public: System::String^ ToString() override
    {
        return this->text;
    }
}; 

因此,一開始的示範程式就可以重新寫成這樣:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        comboBox1.Items.Add(new MyItem("Apple", "Red"));
        comboBox1.Items.Add(new MyItem("Banana", "Yellow"));
        comboBox1.Items.Add(new MyItem("Orange", "Orange XD"));
    }
    private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        textBox1.Text = ((MyItem)comboBox1.SelectedItem).RealValue;
    }
} 

如果是用 C++/CLI 的話,則會變成這樣。

namespace FormatTool {
    public ref class Form1 : public System::Windows::Forms::Form
    {
        public: Form1(void)
            {
                InitializeComponent();
                comboBox1->Items->Add(gcnew MyItem("Apple", "Red"));
                comboBox1->Items->Add(gcnew MyItem("Banana", "Yellow"));
                comboBox1->Items->Add(gcnew MyItem("Orange", "Orange XD"));
            }
        private: System::Void ComboBox1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
            textBox1->Text = ((MyItem^)comboBox1->SelectedItem)->RealValue;
        }
    }
} 

重點就是,此時的 SelectedItem 型態已經變成我們自定義的結構了,所以就可以用自己設定的屬性來得到我們真正想要的值,當然,實際上除了放字串以外,想要放什麼都可以,請大家自由發揮。雖然用 C# 跟 C++/CLI 的寫法會有些不同,不過概念上是一樣的。

示範的結果如下圖,選單中顯示的是 ToString 方法中回傳的值也就是 DisplayName 屬性,而文字框中就可以成功取得 RealValue 屬性值。

搞定!

參考資料

  1. ComboBox 類別 – Microsoft Docs