开发者

Limit on number of items in list box in WinForms

I have a WinForms application which uses a list box to display list of items. My application hangs whent the number of items in the listbox exceeds some 150 items. Is this th开发者_如何学运维e property of ListBox control that it can hold only so many items? If so, I would request you to provide a solution to this problem.

Thanks, Rakesh.


It all depends on what you are binding, if you are binding simple key value pairs you can instantly bind 10k easy. You might want to try adding the items in a loop instead of binding to see if there is a certain item it hangs on.

for (int i = 0; i < 10000; i++)
{
     listBox1.Items.Add("item:" + i.ToString());
}


You can back your listbox by a larger dataset and use a paging mechanism or you can add an event listener for SizeChanged and disable adding when it reaches your max.


First tip, always..

SuspendLayout();
// fill your lists
ResumeLayout();

Second tip, use AddRange when possible.

Third, and it may be overkill, create your own ListBox...

public class LimitedListBox : ListBox
{
    private int _maxItems = 100;

    public LimitedListBox()
    {
        SetItems(new LimitedObjectCollection(this, _maxItems));
    }

    public int MaxItems
    {
        get { return _maxItems; }
        set { _maxItems = value; }
    }

    /// <summary>
    /// This is the only 'bug' - no design time support for Items unless
    /// you create an editor.
    /// </summary>
    public new LimitedObjectCollection Items
    {
        get
        {
            if (base.Items == null)
            {
                SetItems(new LimitedObjectCollection(this, _maxItems));
            }
            return (LimitedObjectCollection) base.Items;
        }
    }

    private void SetItems(ObjectCollection items)
    {
        FieldInfo info = typeof (ListBox).GetField("itemsCollection",
                                                   BindingFlags.NonPublic | BindingFlags.Instance |
                                                   BindingFlags.GetField);
        info.SetValue(this, items);
    }

    #region Nested type: LimitedObjectCollection

    public class LimitedObjectCollection : ObjectCollection
    {
        private int _maxItems;

        public LimitedObjectCollection(ListBox owner, int maxItems)
            : base(owner)
        {
            _maxItems = maxItems;
        }

        public LimitedObjectCollection(ListBox owner, ObjectCollection value, int maxItems)
            : base(owner)
        {
            _maxItems = maxItems;
            AddRange(value);
        }

        public LimitedObjectCollection(ListBox owner, object[] value, int maxItems)
            : base(owner)
        {
            _maxItems = maxItems;
            AddRange(value);
        }

        public int MaxItems
        {
            get { return _maxItems; }
            set { _maxItems = value; }
        }

        public new int Add(object item)
        {
            if (base.Count >= _maxItems)
            {
                return -1;
            }

            return base.Add(item);
        }

        public new void AddRange(object[] items)
        {
            int allowed = _maxItems - Count;
            if (allowed < 1)
            {
                return;
            }

            int length = allowed <= items.Length ? allowed : items.Length;
            var toAdd = new object[length];
            Array.Copy(items, 0, toAdd, 0, length);

            base.AddRange(toAdd);
        }

        public new void AddRange(ObjectCollection value)
        {
            var items = new object[value.Count];
            value.CopyTo(items, 0);

            base.AddRange(items);
        }
    }

    #endregion
}


Why don't you just parse your database something like this.

int Total = yourarray.GetLength(0);

Then all you have to do is this in your new array.

double [] new = double[Total];

array.copy(Total,new);

Now you have an array thats dynamic. Anytime your database grows it automatically populates the new array.

Or if you can do a select count statement on your database you can get the total number or rows and then pipe that to a string. Then you use the string to make control the array. Hope this helps


I just got an "out of memory" error message when filling a list box. The problem was not anything to do with too many items. There was a bug in my code and the items in the list box were returning null in the ToString() method. So the Dot Net error message was wrong and confusing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜