Solved

Overriding the ToString method of SelectedItems property of a ListBox Control

Posted on 2004-08-05
9
1,180 Views
Last Modified: 2010-07-27
Hi

I am trying to create a custom ListBox Control that returns a concatenated string of all the selecteditems. This I have been trying to do it by overriding the ToString method of the 'SelectedObjectCollection' class, but having issues with it. Is there an easy and a better way to do this?

Thanks,
Kalyan
0
Comment
Question by:kkondapalli
9 Comments
 
LVL 10

Expert Comment

by:ibost
ID: 11728856
Are you inheriting the regular ListBox control?

Why not override the ListBox's ToString() method.

public class myListBox: System.Windows.Forms.ListBox
{

      public override string ToString()
      {
            string s = "";
            for (int x = 0; x < this.Items.Count; x++)
            {
                  s += (s.Length > 0) ? ", " : "";
                  s += this.Items[x].ToString();
            }
            return s;
      }

}
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11729034
it would be SelectedItems not Items but other thatn that the above would work.

As for why your mechanism did not work ... you were inheriting from 'SelectedObjectCollection'  but your subclass was not the one being used in the listbox ...
0
 

Author Comment

by:kkondapalli
ID: 11729073
Yes I am inherting the regular ListBox control.

I am looking to concatenate all the selected Items only, and yes i can do that also by creating a new method or override the ToString method of the Listbox control

But conceptually if some other programmer uses this control, he wont that the ToString override for Selected Items is ListBox ToString override, rather he would try to look under the SelectedItems.ToString() method and this is the Method I am trying to overwrite.

I have written some code that basically creates new poperty called TpeSelectedItems to the ListBox which has an overload for the ToString() Method that does the concatenation. It works properly when I have a breakpoint in that loop and run while debugging, but when I remove the debug point and run it, it gives me 'ArgumentOutofRangeException'.  

Also here is the most bizarre thing. If u see the code i have new property for ListBox called TpeSelectedIndices which also has the ToString method that returns the concatenated string of all the selectedIndexes. If i call the TpeSelectedIndices.ToString method before the TpeSelectedItems.ToString method, the later gives me the proper output all the time.


Here is the code snippet For TpeListBox:

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace TpeFormControls
{
      /// <summary>
      /// Summary description for TpeListBox.
      /// </summary>
      public class TpeListBox : System.Windows.Forms.ListBox
      {
            public class TpeSelectedIndexCollection: System.Windows.Forms.ListBox.SelectedIndexCollection
            {
                  public TpeSelectedIndexCollection(ListBox owner): base(owner)
                  {

                  }
                  /// <summary>
                  /// returns a concatenated string of all the selected items
                  /// </summary>
                  /// <param name="seperator">seperator used to concatenate all the selected items</param>
                  /// <returns></returns>
                  public string ToString(Char seperator)
                  {
                        String returnvalue = "";
                        try
                        {                        
                              for (Int32 row = 0; row < this.Count; row++)
                              {
                                    returnvalue += String.Concat(this[row].ToString(), seperator);
                              }
                              if (returnvalue != "")
                                    returnvalue = returnvalue.Remove(returnvalue.Length - 1, 1);
                        }
                        catch (IndexOutOfRangeException _InEx)
                        {
                              MessageBox.Show(_InEx.Message);
                        }
                        return (returnvalue);
                  }
            }
            public class TpeSelectedObjectCollection: System.Windows.Forms.ListBox.SelectedObjectCollection
            {
                  public TpeSelectedObjectCollection(ListBox owner): base(owner)
                  {

                  }
                  /// <summary>
                  /// returns a concatenated string of all the selected items
                  /// </summary>
                  /// <param name="seperator">seperator used to concatenate all the selected items</param>
                  /// <returns></returns>
                  public string ToString(Char seperator)
                  {
                        String returnvalue = "";
                        try
                        {      
                              for (Int32 row = 0; row < this.Count; row++)
                              {
                                    returnvalue += String.Concat(this[row].ToString(), seperator);
                              }
                              if (returnvalue != "")
                                    returnvalue = returnvalue.Remove(returnvalue.Length - 1, 1);
                        }
                        catch (IndexOutOfRangeException _InEx)
                        {
                              MessageBox.Show(_InEx.Message);
                        }
                        return (returnvalue);
                  }
            }
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.Container components = null;
            private TpeFormControls.TpeListBox.TpeSelectedIndexCollection tpeselectedindices;
            private TpeFormControls.TpeListBox.TpeSelectedObjectCollection tpeselecteditems;

            public TpeListBox()
            {
                  // This call is required by the Windows.Forms Form Designer.
                  InitializeComponent();

                  // TODO: Add any initialization after the InitializeComponent call

                  tpeselectedindices = new TpeSelectedIndexCollection(this);
                  tpeselecteditems = new TpeSelectedObjectCollection(this);
            }

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if(components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            
            #region Component Designer generated code
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  components = new System.ComponentModel.Container();
            }
            #endregion

            public TpeFormControls.TpeListBox.TpeSelectedIndexCollection TpeSelectedIndices
            {
                  get {return tpeselectedindices;}
            }
            public TpeFormControls.TpeListBox.TpeSelectedObjectCollection TpeSelectedItems
            {
                  get {return tpeselecteditems;}
            }

      }
}

Here is the Code Snippet from the sample app where i am using this control


            private void button1_Click(object sender, System.EventArgs e)
            {
                  tpeListBox1.Refresh();
                  //MessageBox.Show(this.tpeListBox1.TpeSelectedIndices.Count.ToString());
                  MessageBox.Show(this.tpeListBox1.SelectedItems.Count.ToString());
                  //MessageBox.Show(this.tpeListBox1.TpeSelectedIndices.ToString(','));                  
                  MessageBox.Show(this.tpeListBox1.TpeSelectedItems.ToString(','));
            }

            private void tpeListBox1_SelectedIndexChanged(object sender, System.EventArgs e)
            {
                  //MessageBox.Show(this.tpeListBox1.TpeSelectedIndices.Count.ToString());
                  MessageBox.Show(this.tpeListBox1.SelectedItems.Count.ToString());                                    
                  //MessageBox.Show(this.tpeListBox1.TpeSelectedIndices.ToString(','));                  
                  MessageBox.Show(this.tpeListBox1.TpeSelectedItems.ToString(','));
            }


Hope this makes the question more clear
0
 
LVL 9

Assisted Solution

by:s_sansanwal
s_sansanwal earned 100 total points
ID: 11731350
Change code

                         for (Int32 row = 0; row < this.Count; row++)
                         {
                              returnvalue += String.Concat(this[row].ToString(), seperator);
                         }

to

foreach(object item in this)
{
returnvalue += String.Concat(item.ToString(), seperator);
}
avoid out of index error
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:kkondapalli
ID: 11731763
Hi sansanwal,

Thanks for the tip, now I am not getting the Out of range Error, but this time, its not refreshing the selectedItem value, it always shows the first Item that was selected. For Eg: I have the following values in the list
Line1
Line2
Line3
Line4
Line5

Now the first time I select Line3, the ToString Method return value is Line3, but from then on when i try to select a different item, it still gives me Line3 as the return value.

Thanks,
Kalyan.
0
 

Author Comment

by:kkondapalli
ID: 11731793
Again as I said, the above logic works fine when I am stepping thru the code in the debug mode. But when not in debug mode, it gives me the wrong selected Items.
0
 
LVL 9

Expert Comment

by:s_sansanwal
ID: 11731885
It seems the selecteditems is not set before calling your custom collection

I think you need to call
this.tpeListBox1.SelectedItem.ToString(); // Just write this code in button click before messagebox
in button click event to re-initalise your collection

0
 
LVL 1

Accepted Solution

by:
hammadraza earned 400 total points
ID: 11733566
Hi kkondapalli,

Just change the property "TpeSelectedItems" with code below

public TpeFormControls.TpeListBox.TpeSelectedObjectCollection TpeSelectedItems
{
                  
      get {

                 tpeselecteditems = new TpeSelectedObjectCollection(this);
                 return tpeselecteditems;
           }
}


Hope it will work.

0
 

Author Comment

by:kkondapalli
ID: 11735784
hammadraza -
 Your solution worked like a charm. It all makes sense now why the collection was not getting refreshed. Thanks a lot for that.

Thanks a lot guys for taking time to take a look at the problem.

Thanks,
Kalyan.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now