ComboBox:テキストと値をアイテムに追加(バインディングソースなし)


202

C#WinAppで、ComboBoxの項目にテキストと値の両方を追加するにはどうすればよいですか?私は検索を行いましたが、通常は "Binding to a source"を使用していますが、私の場合、プログラムにバインドソースが用意されていません...このようにするにはどうすればよいですか。

combo1.Item[1] = "DisplayText";
combo1.Item[1].Value = "useful Value"

回答:


361

独自のクラス型を作成し、ToString()メソッドをオーバーライドして必要なテキストを返す必要があります。次に、使用できるクラスの簡単な例を示します。

public class ComboboxItem
{
    public string Text { get; set; }
    public object Value { get; set; }

    public override string ToString()
    {
        return Text;
    }
}

以下は、その使用法の簡単な例です。

private void Test()
{
    ComboboxItem item = new ComboboxItem();
    item.Text = "Item text1";
    item.Value = 12;

    comboBox1.Items.Add(item);

    comboBox1.SelectedIndex = 0;

    MessageBox.Show((comboBox1.SelectedItem as ComboboxItem).Value.ToString());
}

4
この新しいクラスComboboxItemが本当に必要ですか?ListItemという名前のものがすでに存在していると思います。
Amr Elgarhy

15
私はそれがWinFormsではなくASP.NETでのみ利用可能かもしれないと信じています。
アダムマルコヴィッツ

1
いいえ。アイテムは、アイテムのデータ(テキスト、値、他のオブジェクトへの参照など)を格納するためにのみ使用される別のタイプです。これはComboBoxの子孫ではなく、そうなることは非常にまれです。
Adam Markowitz、2010年

1
私はパーティーにいくらか遅れていることを知っていますが、純粋なWindowsフォーム環境でこれを行う方法は、データテーブルを設定し、それにアイテムを追加し、コンボボックスをデータテーブルにバインドすることでした。よりクリーンな方法があるはずだと思う人もいますが、見つかりませんでした(DisplayMemberは、テキストを表示するために必要なコンボボックスのプロパティであり、ValueMemberはデータの値です)
user2366842

4
「SelectedValue」を取得する方法、または値に基づいてアイテムを選択する方法...返信してください
Alpha Gabriel V. Timbol

185
// Bind combobox to dictionary
Dictionary<string, string>test = new Dictionary<string, string>();
        test.Add("1", "dfdfdf");
        test.Add("2", "dfdfdf");
        test.Add("3", "dfdfdf");
        comboBox1.DataSource = new BindingSource(test, null);
        comboBox1.DisplayMember = "Value";
        comboBox1.ValueMember = "Key";

// Get combobox selection (in handler)
string value = ((KeyValuePair<string, string>)comboBox1.SelectedItem).Value;

2
完璧に動作し、これが選択された答えになるはずです。しかし、.SelectedItemをキャストして.Valueを取る代わりに、comboBox1.SelectedTextを使用することはできませんか?
Jeffrey Goines 14

@fabコンボボックスで特定のキーを持つアイテムをどのように見つけますか
Smith

辞書キーに基づいてコンボボックス内のアイテムを選択することは可能ですか?キー3を選択するように、キー3のアイテムが選択されます。
Dror

この方法はvs2015では機能しなくなりました。新しいディスプレイメンバーとバリューメンバーにバインドできないという例外がスローされる
Plater

119

次のような匿名クラスを使用できます。

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

comboBox.Items.Add(new { Text = "report A", Value = "reportA" });
comboBox.Items.Add(new { Text = "report B", Value = "reportB" });
comboBox.Items.Add(new { Text = "report C", Value = "reportC" });
comboBox.Items.Add(new { Text = "report D", Value = "reportD" });
comboBox.Items.Add(new { Text = "report E", Value = "reportE" });

更新:上記のコードはコンボボックスに正しく表示されますが、SelectedValueまたはのSelectedTextプロパティを使用することはできませんComboBox。これらを使用できるようにするには、コンボボックスを次のようにバインドします。

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

var items = new[] { 
    new { Text = "report A", Value = "reportA" }, 
    new { Text = "report B", Value = "reportB" }, 
    new { Text = "report C", Value = "reportC" },
    new { Text = "report D", Value = "reportD" },
    new { Text = "report E", Value = "reportE" }
};

comboBox.DataSource = items;

14
プログラマはこれに加えてforループを必要とする可能性が高いため、これを少し変更したいと思います。配列の代わりにリストList<Object> items = new List<Object>(); を使用してitems.Add( new { Text = "report A", Value = "reportA" } );、ループ内でメソッドを使用することができました。
Andrew

1
アンドリュー、List <Object>をSelectedValueプロパティで使用できるようにしましたか?
Peter PitLock、2015年

@Venkat、comboBox.SelectedItem.GetType().GetProperty("Value").GetValue(comboBox.SelectedItem, null)
Optavius 16

2
@Venkat コンボボックスのまたはプロパティをDataSource使用できるように設定する2番目のソリューションを使用するSelectedValue場合SelectedText、特別なキャストを行う必要はありません。
JPProgrammer 2017年

32

dynamic実行時にコンボボックス項目を解決するには、オブジェクトを使用する必要があります。

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Value";

comboBox.Items.Add(new { Text = "Text", Value = "Value" });

(comboBox.SelectedItem as dynamic).Value

1
これは、別個のクラスを作成してToString()をオーバーライドするよりもはるかに優れています。
Don Shrout、2018年

1
dynamicはC#4以降でのみ使用できます。(.NET 4.5だと思います)
MickeyfAgain_BeforeExitOfSO 2018年

シンプルで書きやすい!VB.netのSelectedValueに対してこれを行いました:Dim Value As String = CType(Me.SectionIDToComboBox.SelectedItem、Object).Value
Mambo

1
次に、「値」を使用して正しいコンボボックス項目を設定するにはどうすればよいですか。
Dave Ludwig、

17

Dictionaryテキストと値を追加するカスタムクラスを作成する代わりに、Object を使用できますCombobox

Dictionaryオブジェクトにキーと値を追加します。

Dictionary<string, string> comboSource = new Dictionary<string, string>();
comboSource.Add("1", "Sunday");
comboSource.Add("2", "Monday");

ソースディクショナリオブジェクトをにバインドしますCombobox

comboBox1.DataSource = new BindingSource(comboSource, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";

キーと値を取得します。

string key = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Key;
string value = ((KeyValuePair<string,string>)comboBox1.SelectedItem).Value;

完全なソース:コンボボックスのテキストと値


14

これは、思いついた方法の1つです。

combo1.Items.Add(new ListItem("Text", "Value"))

そして、アイテムのテキストまたは値を変更するには、次のようにします。

combo1.Items[0].Text = 'new Text';

combo1.Items[0].Value = 'new Value';

WindowsフォームにはListItemというクラスはありません。これはASP.NETにのみ存在するため、使用する前に独自のクラスを作成する必要があります。@ Adam Markowitzが彼の回答で行ったのと同じです

これらのページもチェックしてください。


2
私が間違っていない限り、ListItemはASP.NETでのみ使用できます
Adam Markowitz

はい:(残念ながら、それはASP.netにのみ存在します...それで、私は今何ができますか?
Bohn

次に、コンボボックスのSelectedValueプロパティまたはSelectedTextプロパティのポイントは何ですか?
JSON

11

これが元の投稿で与えられた状況でうまくいくかどうかはわかりません(これが2年後であることを気にしないでください)。この例は私にとってはうまくいきます:

Hashtable htImageTypes = new Hashtable();
htImageTypes.Add("JPEG", "*.jpg");
htImageTypes.Add("GIF", "*.gif");
htImageTypes.Add("BMP", "*.bmp");

foreach (DictionaryEntry ImageType in htImageTypes)
{
    cmbImageType.Items.Add(ImageType);
}
cmbImageType.DisplayMember = "key";
cmbImageType.ValueMember = "value";

値を読み戻すには、SelectedItemプロパティをDictionaryEntryオブジェクトにキャストする必要があります。その後、そのKeyプロパティとValueプロパティを評価できます。例えば:

DictionaryEntry deImgType = (DictionaryEntry)cmbImageType.SelectedItem;
MessageBox.Show(deImgType.Key + ": " + deImgType.Value);

7
//set 
comboBox1.DisplayMember = "Value"; 
//to add 
comboBox1.Items.Add(new KeyValuePair("2", "This text is displayed")); 
//to access the 'tag' property 
string tag = ((KeyValuePair< string, string >)comboBox1.SelectedItem).Key; 
MessageBox.Show(tag);

5

まだこれに興味がある場合は、テキストと任意のタイプの値を持つコンボボックス項目のシンプルで柔軟なクラスを次に示します(Adam Markowitzの例に非常に似ています)。

public class ComboBoxItem<T>
{
    public string Name;
    public T value = default(T);

    public ComboBoxItem(string Name, T value)
    {
        this.Name = Name;
        this.value = value;
    }

    public override string ToString()
    {
        return Name;
    }
}

を使用すること<T>は、をvalueとして宣言するよりも優れobjectています。objectあなたは、あなたがそれぞれのアイテムに使用されるタイプのトラックを保持する必要があるだろう、とすると、それを正しく使用するようにコードでそれをキャスト。

私はかなり長い間、私のプロジェクトでそれを使用しています。本当に重宝しています。


4

私はfabの答えが好きでしたが、私の状況では辞書を使いたくなかったので、タプルのリストを置き換えました。

// set up your data
public static List<Tuple<string, string>> List = new List<Tuple<string, string>>
{
  new Tuple<string, string>("Item1", "Item2")
}

// bind to the combo box
comboBox.DataSource = new BindingSource(List, null);
comboBox.ValueMember = "Item1";
comboBox.DisplayMember = "Item2";

//Get selected value
string value = ((Tuple<string, string>)queryList.SelectedItem).Item1;

3

DataTableを使用した例:

DataTable dtblDataSource = new DataTable();
dtblDataSource.Columns.Add("DisplayMember");
dtblDataSource.Columns.Add("ValueMember");
dtblDataSource.Columns.Add("AdditionalInfo");

dtblDataSource.Rows.Add("Item 1", 1, "something useful 1");
dtblDataSource.Rows.Add("Item 2", 2, "something useful 2");
dtblDataSource.Rows.Add("Item 3", 3, "something useful 3");

combo1.Items.Clear();
combo1.DataSource = dtblDataSource;
combo1.DisplayMember = "DisplayMember";
combo1.ValueMember = "ValueMember";

   //Get additional info
   foreach (DataRowView drv in combo1.Items)
   {
         string strAdditionalInfo = drv["AdditionalInfo"].ToString();
   }

   //Get additional info for selected item
    string strAdditionalInfo = (combo1.SelectedItem as DataRowView)["AdditionalInfo"].ToString();

   //Get selected value
   string strSelectedValue = combo1.SelectedValue.ToString();

3

このコードを使用して、テキストと値を含むいくつかの項目をコンボボックスに挿入できます。

C#

private void ComboBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
    combox.Items.Insert(0, "Copenhagen");
    combox.Items.Insert(1, "Tokyo");
    combox.Items.Insert(2, "Japan");
    combox.Items.Insert(0, "India");   
}

XAML

<ComboBox x:Name="combox" SelectionChanged="ComboBox_SelectionChanged_1"/>

解決策を説明してください。
Vaibhav Bajaj 2017

簡単に言えば、コンボボックスのそれぞれのインデックスに次の国を追加します。インデックスが0のオプションを含むコンボックスが表示されます。コンボックスをクリックすると、次のオプションが表示されます
Muhammad Ahmad

これはidでは機能しません。これは、単にリストにインデックスを付ける方法であり、それは問題に関するものではありませんでした
Mr Heelis

2

Adam Markowitzの回答に加えてItemSource、コンボボックスの値を(比較的)単純に設定しenums、 '説明'属性をユーザーに表示する一般的な方法を次に示します。(誰もが.NETの 1つのライナーになるようにこれを実行したいと思うでしょうが、そうではありません。これは私が見つけた最もエレガントな方法です)。

最初に、任意のEnum値をComboBox項目に変換するためのこの単純なクラスを作成します。

public class ComboEnumItem {
    public string Text { get; set; }
    public object Value { get; set; }

    public ComboEnumItem(Enum originalEnum)
    {
        this.Value = originalEnum;
        this.Text = this.ToString();
    }

    public string ToString()
    {
        FieldInfo field = Value.GetType().GetField(Value.ToString());
        DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
        return attribute == null ? Value.ToString() : attribute.Description;
    }
}

次に、OnLoadイベントハンドラーで、コンボボックスのソースを、型のComboEnumItemsすべてEnumに基づくリストになるように設定する必要がありますEnum。これはLinqで実現できます。次に、単にDisplayMemberPath

    void OnLoad(object sender, RoutedEventArgs e)
    {
        comboBoxUserReadable.ItemsSource = Enum.GetValues(typeof(EMyEnum))
                        .Cast<EMyEnum>()
                        .Select(v => new ComboEnumItem(v))
                        .ToList();

        comboBoxUserReadable.DisplayMemberPath = "Text";
        comboBoxUserReadable.SelectedValuePath= "Value";
    }

これでユーザーは、ユーザーフレンドリーのリストから選択しますDescriptionsが、彼らが選択することになりenumますが、コードで使用できる値。コードでユーザーの選択にアクセスcomboBoxUserReadable.SelectedItemするには、ComboEnumItemとにcomboBoxUserReadable.SelectedValueなりますEMyEnum


1

一般的なタイプを使用できます:

public class ComboBoxItem<T>
{
    private string Text { get; set; }
    public T Value { get; set; }

    public override string ToString()
    {
        return Text;
    }

    public ComboBoxItem(string text, T value)
    {
        Text = text;
        Value = value;
    }
}

単純なint-Typeの使用例:

private void Fill(ComboBox comboBox)
    {
        comboBox.Items.Clear();
        object[] list =
            {
                new ComboBoxItem<int>("Architekt", 1),
                new ComboBoxItem<int>("Bauträger", 2),
                new ComboBoxItem<int>("Fachbetrieb/Installateur", 3),
                new ComboBoxItem<int>("GC-Haus", 5),
                new ComboBoxItem<int>("Ingenieur-/Planungsbüro", 9),
                new ComboBoxItem<int>("Wowi", 17),
                new ComboBoxItem<int>("Endverbraucher", 19)
            };

        comboBox.Items.AddRange(list);
    }

0

私は同じ問題を抱えていましたがComboBox、最初のインデックスと同じインデックスの値だけで新しいものを追加し、次に2番目のインデックスのプリンシパルコンボを変更すると、同時に値が変更されました。 2番目のコンボの使用します。

これはコードです:

public Form1()
{
    eventos = cliente.GetEventsTypes(usuario);

    foreach (EventNo no in eventos)
    {
        cboEventos.Items.Add(no.eventno.ToString() + "--" +no.description.ToString());
        cboEventos2.Items.Add(no.eventno.ToString());
    }
}

private void lista_SelectedIndexChanged(object sender, EventArgs e)
{
    lista2.Items.Add(lista.SelectedItem.ToString());
}

private void cboEventos_SelectedIndexChanged(object sender, EventArgs e)
{
    cboEventos2.SelectedIndex = cboEventos.SelectedIndex;
}

0

クラス作成:

namespace WindowsFormsApplication1
{
    class select
    {
        public string Text { get; set; }
        public string Value { get; set; }
    }
}

Form1コード:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            List<select> sl = new List<select>();
            sl.Add(new select() { Text = "", Value = "" });
            sl.Add(new select() { Text = "AAA", Value = "aa" });
            sl.Add(new select() { Text = "BBB", Value = "bb" });
            comboBox1.DataSource = sl;
            comboBox1.DisplayMember = "Text";
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

            select sl1 = comboBox1.SelectedItem as select;
            t1.Text = Convert.ToString(sl1.Value);

        }

    }
}

0

これはVisual Studio 2013が行う方法です。

単品:

comboBox1->Items->AddRange(gcnew cli::array< System::Object^  >(1) { L"Combo Item 1" });

複数のアイテム:

comboBox1->Items->AddRange(gcnew cli::array< System::Object^  >(3)
{
    L"Combo Item 1",
    L"Combo Item 2",
    L"Combo Item 3"
});

クラスのオーバーライドを行ったり、その他を含める必要はありません。そして、そうcomboBox1->SelectedItemcomboBox1->SelectedIndex通話まだ仕事。


0

これは他のいくつかの回答と似ていますが、コンパクトであり、リストが既にある場合は辞書への変換を回避できます。

ComboBoxWindowsフォーム上の「コンボボックス」とtypeプロパティを持つクラスSomeClassを考えると、stringName

List<SomeClass> list = new List<SomeClass>();

combobox.DisplayMember = "Name";
combobox.DataSource = list;

つまり、SelectedItemはのSomeClassオブジェクトlistであり、の各アイテムはcomboboxその名前を使用して表示されます。


ほんとだ!私はDisplayMember以前に使用したことがあります...それが存在することをいつも忘れます。このプロパティに注意を払う前に見つけた解決策に慣れましたが、常に役立つとは限りません。すべてのクラスにNameor Tagプロパティがあるわけではありません。また、表示テキストとして任意に使用できる文字列プロパティがあるわけでもありません。
Matheus Rocha 2017

これは良い点です。クラスを変更できる場合、そのようなプロパティをクラスに追加することは価値があります。たとえば、プロパティ 'ComboBoxText'(使用可能な場合はToString()メソッドを返す可能性があります)または、クラスを変更できない場合は、「ComboBoxText」プロパティを実装できる派生クラスを作成できる可能性があります。これは、クラスをComboBoxに何度も追加する必要がある場合にのみ価値があります。それ以外の場合は、他の回答の1つで説明されているように、辞書を使用する方が簡単です。
Alex Smith

こんにちはアレックス、私はこれらのケースで通常使用する方法で答えを出しました。私はあなたが言ったことにかなり近いか、私はあなたが言ったことを理解していなかったと思います。一部のクラスではオーバーライドしたくないメソッドを実装する必要がある場合があるため、クラスから派生しませんでした(そのため、単純なbase.Method();で多数のメソッドを作成します)。また、派生クラスを作成する必要があります。コンボボックスまたはリストボックスに追加するタイプごとに。私が作ったクラスは柔軟性があり、どんなタイプでも余計な手間をかけずに使うことができます。以下の私の答えを見て、あなたの考えを教えてください:)
Matheus Rocha

確かに、あなたの答えは、コンボボックスに追加したいタイプごとに派生クラスを作成するよりも間違いなく便利に思えます。良くやった!今後、「名前」のようなプロパティがすぐに利用できない場合は、あなたの答えや辞書の答えのようなものを使用するつもりだと思います:)
Alex Smith

0

これは、(文字列)としての最終的な値がすべて必要な場合の、Windowsフォームの非常に単純なソリューションです。アイテムの名前がコンボボックスに表示され、選択した値を簡単に比較できます。

List<string> items = new List<string>();

// populate list with test strings
for (int i = 0; i < 100; i++)
            items.Add(i.ToString());

// set data source
testComboBox.DataSource = items;

イベントハンドラーで、選択した値の値(文字列)を取得します

string test = testComboBox.SelectedValue.ToString();

0

ここでより良いソリューション;

Dictionary<int, string> userListDictionary = new Dictionary<int, string>();
        foreach (var user in users)
        {
            userListDictionary.Add(user.Id,user.Name);
        }

        cmbUser.DataSource = new BindingSource(userListDictionary, null);
        cmbUser.DisplayMember = "Value";
        cmbUser.ValueMember = "Key";

データを取得する

MessageBox.Show(cmbUser.SelectedValue.ToString());

コンボボックスを埋めることはできましたが、それをクリックするとVS2019でこのエラーが発生します。COM可視マネージクラス 'ComboBoxUiaProvider
MC9000
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.