2

次のコードを検討してください。これは、私が作成したユーザー コントロール内に実装したプロセスを簡略化したものです。

//MyUserControl Constructor
public MyUserControl(field, value)
{
    InitializeComponents();
    string cType = resolveControlType(field);
    switch (cType)
    {
        ...
        case "ComboBox":  AddComboBox(field, value);
        ...
    }
}

AddComboBox(string fieldID, object value)
{
    ComboBox cbo = new ComboBox();
    cbo.DisplayMember = "DisplayMember";
    cbo.ValueMember = "ValueMember";

    //We set the DataSource to a DataTable
    cbo.DataSource = DBCaller.GetListAsDataTable(fieldID);
    this.Controls.Add(cbo);
    cbo.SelectedValue = value; //<-- Weird stuff happening here?!
                               //    If you don't break here, it  
                               //    doesn't look like the correct 
                               //    record is selected.
                               //    However, add a breakpoint,
                               //    scroll through cbo's properties
                               //    and this assignment will work
                               //    properly when you continue?!
}

私の問題は、値をコントロールに割り当てると、ComboBox のテキストに DataSource テーブルの最初の項目が表示されることです。

ただし、cbo.SelectedValue = value;行にブレークポイントを設定し、Intellisense を使用して ComboBox に関連付けられたプロパティをスクロールすると、ComboBox で何かが初期化され、この問題が修正されます。コードの実行を続けると、ComboBox に表示された適切な値でフォームが読み込まれます。

何が起こっていますか?どうすれば修正できますか?

4

2 に答える 2

2

あなたの問題を解決する方法を見つけましたが、その理由を説明するのは簡単ではありません。ここで興味深いものを見つけました。まず、物事を整理する方法を少なくとも 2 つ見つけたと言いたいです。これら2つの方法のコードは次のとおりです。

//Solution 1
//Simply you have to add the ComboBox to the parent control first
//before assigning its DataSource
this.Controls.Add(cbo);   //<---- This goes first
cbo.DataSource = DBCaller.GetListAsDataTable(fieldID); //<--- This goes after
cbo.SelectedValue = value;

//Solution 2
//This is very strange and interesting, you can also add your ComboBox to 
//the parent control after assigning its DataSource (as in your code).
//But you have to ACCESS to the BindingContext property of your ComboBox
//I would like to emphasize the ACCESS, you can perform any kind of access (Read and Write).
//Here are some examples of such access:
cbo.DataSource = DBCaller.GetListAsDataTable(fieldID);
this.Controls.Add(cbo);  //<--- like in your code, this is placed here after the DataSource is assigned
//here you can ACCESS the BindingContext
var whatEver = cbo.BindingContext;//READ access
if(cbo.BindingContext == null) Text = "????"; //READ access and of course it's not null
cbo.BindingContext = new BindingContext();//WRITE access
cbo.SelectedValue = value; //<---- This should be placed here after all.

最初の解決策は理解できますが、2番目の解決策は非常に奇妙で説明が難しいことがわかりました(少なくとも2番目の解決策は見つかりませんでした)。

于 2013-08-20T20:45:07.220 に答える
0

私もそれに会います。しかし、私のコンボはまだフォームに追加されていないパネルにあります。今、私はついにこの方法を見つけました:

            //FAILED cboField.SelectedValue = value;
            //FAILED cboField.HandleCreated += ;
            //FAILED cboField.SelectedItem = item;
            //FAILED cboField.SelectedIndex = indexOfItem;
            cboField.BindingContextChanged += (s1, e2) => {
                cboField.SelectedValue = value;
            };   

失敗したすべての方法をもう一度試す必要はありません。

于 2013-12-23T08:30:44.680 に答える