0

わかりましたので、GUIで作成された選択によってリストをクリアし、新しく選択されたものをフィードするこの関数があります...非常に単純です:コンストラクターとオーバーライドされたToStringメソッドを持つクラスがリストにスローされ、リストボックスのデータソースとして機能します...私が作成したテストはすべて問題なく機能しますが、この特定のプログラムでは機能しません。理由がわかりません。私は絶望的ではありません、ただ本当に興味があります。

List<> を配列に変換するだけで機能することがわかりました...しかし、なぜですか?

これは動作しない私の元のコードです:

private void QaControl(string _itemNo, int _curIndex)
    {
        List<QaControlPoint> list = new List<QaControlPoint>();

        //remove old ones from list 
        if (listBox1.DataSource != null)
        {
            list = (List<QaControlPoint>)listBox1.DataSource;

            for (int n = listBox1.Items.Count - 1; n >= 0; --n)
            {
                QaControlPoint qcp = (QaControlPoint)listBox1.Items[n];
                if (_boxList.IndexOf(qcp.link_box) >= _curIndex)
                    list.Remove(qcp);
            }
        }

        string fs = service.getQa(Int32.Parse(_itemNo), "R");
        string[] temp = fs.Split('@');
        for (int a = 0; a < temp.Length - 1; a++)
            list.Add(new QaControlPoint(temp[a], _boxList[_curIndex]));
        listBox1.DataSource = list;
    }

このコードでは、データソースとして単純な配列を使用して完璧に動作します。

private void QaControl(string _itemNo, int _curIndex)
    {
        List<QaControlPoint> list1 = new List<QaControlPoint>();

        //remove old ones from list 
        if (listBox1.DataSource != null)
        {
            //convert to list here
            QaControlPoint[] rcp = (QaControlPoint[])listBox1.DataSource;
            list1.AddRange(rcp);

            QaControlPoint rcp2;
            for (int n = listBox1.Items.Count - 1; n >= 0; --n)
            {
                rcp2 = (QaControlPoint)listBox1.Items[n];
                if (_boxList.IndexOf(rcp2.link_box) >= _curIndex)
                    list1.Remove(rcp2);
            }
        }

        string fs = service.getQa(Int32.Parse(_itemNo), "R");
        string[] temp = fs.Split('@');
        for (int a = 0; a < temp.Length - 1; a++)
            list1.Add(new QaControlPoint(temp[a], _boxList[_curIndex]));

        //convert back to array here
        QaControlPoint[] rcnew = list1.ToArray();
        listBox1.DataSource = rcnew;
    }
4

1 に答える 1

0

ここでは推測ですが、最初の例では、DataSourceプロパティは変更されません。確かに、アイテムを追加および削除していますが、データソースを設定すると、すでに持っていたのと同じオブジェクトインスタンスに設定されます。

2番目の例では、新しいインスタンスを使用しています(両方とも新しいリスト、次に新しい配列)。

私の推測では、ListBoxは、同じインスタンスに設定しているときにDataSourceの値を変更していないことを認識できるほど賢いので、それ自体を更新するという非常にコストのかかる手順を実行していません。List<T>これは、私があまりよく知らないWinFormsのように見えますが、コレクションの変更されたイベントをキャッチするためにListBoxに必要なインターフェイスを実装しているとは思いません。

代わりにこれを試してください:

    private void QaControl( string _itemNo, int _curIndex ) {
        List<QaControlPoint> list = new List<QaControlPoint>();

        //remove old ones from list         
        if ( listBox1.DataSource != null ) {
            List<QaControlPoint> oldList = (List<QaControlPoint>) listBox1.DataSource;
            list.AddRange( oldList );
            for ( int n = listBox1.Items.Count - 1; n >= 0; --n ) {
                QaControlPoint qcp = (QaControlPoint) listBox1.Items[n];
                if ( _boxList.IndexOf( qcp.link_box ) >= _curIndex )
                    list.Remove( qcp );
            }
        }

        string fs = service.getQa( Int32.Parse( _itemNo ), "R" );
        string[] temp = fs.Split( '@' );
        for ( int a = 0; a < temp.Length - 1; a++ )
            list.Add( new QaControlPoint( temp[a], _boxList[_curIndex] ) );
        listBox1.DataSource = list;
    }
于 2012-09-07T13:48:18.147 に答える