0

好的,所以我有这个函数,它通过 gui 中的选择清除列表并提供新选择的内容......它非常简单:一个具有构造函数和重写 ToString 方法的类被扔到 List 中并用作列表框的数据源...我进行的任何测试,这都完美无缺,但在这个特定的程序中却没有,我不知道为什么。我并不绝望,我只是真的很好奇。

我发现如果我只是将 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 属性从未更改。当然,您正在添加和删除项目,但是当您设置 DataSource 时,您将它设置为它已经拥有的相同对象实例。

在第二个示例中,您正在使用一个新实例(一个新的 List,然后又是一个新的 Array)。

我的猜测是 ListBox 足够聪明,可以识别出在设置相同实例时不会更改 DataSource 的值,因此它不会执行非常昂贵的刷新步骤。这看起来像 WinForms,我不太熟悉,但我不认为它List<T>实现了 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 回答