質問

DataTableを使用してXMLファイルからComboBoxにアイテムを入力しています。現在、1つの列がComboBoxのディスプレイメンバーであり、別の列が値メンバーであるように設定しています。ただし、selectedItemパラメーターを設定する必要があり、値メンバーが一意でない可能性があるため、これは常に機能するとは限りません。

テーブルに値メンバーの重複があるかどうかわからないため、ComboBoxの値メンバーとしてDataRow全体を配置し、ComboBox.SelectedITem =(DataRow)を使用することを考えましたsome_data_row;を選択します。常に正しいComboBoxオブジェクトが選択されます。

これをどのように達成しますか?これを行うより良い方法はありますか?私は提案を受け入れますが、表示メンバーと価値メンバーの両方に到達できることが非常に重要です。

ご協力ありがとうございます!

編集:以前は十分に明確ではなかったかもしれませんが、ここでこれが最善のアプローチであるかどうかを尋ねている間、私はこれを行う方法方法も尋ねています。 valuememberパラメーターを設定しない場合、SelectedItemはDataRowViewタイプです... selectedValueパラメーターを使用してComboBoxから項目を選択し、値メンバーを明示的に設定せずにそれを実行しようとすると、例外がスローされます。

役に立ちましたか?

解決 2

まず、アダム・ロビンソンに感謝します。あなたの答えは正しかったと確信していますが、それは私が聞きたかったことではありませんでした。別の方法で問題を解決しましたが、他の誰かに役立つかもしれないと思うので、ここに投稿しています。

やったことは、新しいクラスを作成したことです。私の場合は、プロパティDataRowを持つListObjectという名前を付けました(後でわかるように、他の型でも動作します。私のアイテム値プロパティとして)。また、メソッドをオーバーライドします:

  • String ToString()
  • bool Equals(object obj)
  • int GetHashCode()-私の場合は必要ありませんが、Visual Studio
    オーバーライドする必要があることを警告します。

アイデアは、ComboBox.Itemsコレクションを自分のクラスのオブジェクトで埋め、カスタム文字列を表示できるというものでした(このように解決しなかった場合、スタックオーバーフローに関する次の質問は、おそらく読み取り時にDisplayMembersをカスタマイズすることですDataRowからのアイテム)と1つのクラスのアイテム(私の場合はDataRow)のみを比較します。

コードはここにあり、素晴らしい動作をします(少なくとも私がそれでやりたかったことには)。

public class ListObject
{
    public DataRow element;

    public String DisplayObject = null;

    public ListObject(DataRow dr)
    {
        element = dr;
    }

    public ListObject(DataRow dr, String dspObject)
    {
        element = dr;
        DisplayObject = dspObject;
    }

    public override String ToString()
    {
        if (DisplayObject == null) throw new Exception("DisplayObject property was not set.");

        return element[DisplayObject].ToString();
    }

    public override bool Equals(object obj)
    {
        if (obj.GetType() == typeof(ListObject))
            return Equals(((ListObject)obj).element, this.element);
        else return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

ComboBoxにforeachステートメントを入力するだけでよいので、私の場合はうまくいきます:

dtUsers.ReadXml(Program.Settings.xmlInputUsers);

foreach(DataRow dr in dtUsers.Rows) 
{
    cmbUser.Items.Add(new ListObject(dr, "Name"));
}

そして、選択したいDataRowを取得したら、これを行うだけです:

cmbUser.SelectedItem = new ListObject(dlg.SelectedDataRow);

DataMeのみが比較され、ComboBox.Itemsコレクションを入力したときから表示パラメーターが設定されるため、DisplayMemberなどについて心配する必要はありません。また、toStringメソッドはオーバーライドされるため、出力を実際にカスタマイズできます。

このクラスの作成は、 ComboBox.SelectedItem Property のmsdn記事(SelectedItemプロパティはIndexOfメソッドを使用して機能する)が原因でのみ可能でした。このメソッドはEqualsメソッドを使用して同等性を判断します。

他のヒント

ListBox DataTable にバインドすると、実際には DataTable <を表す DataView にバインドされます/ code>( DataTable IListSource を実装し、 DataView を返します)。 SelectedItem DataRow インスタンスに直接設定することはできません。 DataRowView インスタンスに設定する必要があります。残念ながら、 DataRow から DataRowView を取得する簡単な方法はありません。

DataRowView を介してすべての対話を行う方がよいでしょう。これにより、 SelectedItem を明示的に設定できます。

SelectedValue プロパティは使用できません。これには SelectedItem を使用する必要があります。

これは、DataTableをコンボボックスに取得する最も簡単な方法です

private void load() { 
DataTable dt = // get data from DB 
comboBox1.ValueMember = null; // allows you to get all fields in the obj to combobox
comboBox1.DisplayMember = "ccType";//label displayed from dt
comboBox1.DataSource = dt;
}
//to test 
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {

        DataRowView current = (DataRowView)comboBox1.SelectedValue;
        string drs = current.Row["ID"].ToString();

    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top