Click here to Skip to main content
15,879,239 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
how to use items of listbox as an event

e.g i create one list box listbox1

ant the items are
1
2
3
4
5
if i click on 1 form1 display
if i click on 2 form2 display
if i click on 3 form3 display
if i click on 4 form4 display
if i click on 5 form5 display


how to do this
Posted

Please see my comments to the interesting solution by Tarun. I would offer alternative solution based on his idea, which is not maintainable and needs improvement.

The idea is to populate list box based on the form type present in the current assembly to get guaranteed one-to-one correspondence.

C#
public partial class MyMainForm : Form {
    
    public MyMainForm() {
        InitializeComponent();
        TypeList typeList = new TypeList();
        Type currentType = this.GetType();
        Type[] types = Assembly.GetExecutingAssembly().GetTypes();
        foreach (Type type in types) {
            if (!type.IsClass) continue;
            if (type == currentType) continue; //excluding the present form type
            if (type.BaseType == typeof(Form))
                typeList.Add(type);
        } //loop
        RelevantForms = new Form[typeList.Count];
        int index = 0;
        foreach (Type type in typeList) {
            RelevantForms[index] = (Form)Activator.CreateInstance(type);
            MyListBox.Items.Add(type);
            ++index;
        } //loop
        MyListBox.SelectedIndexChanged += (sender, eventArgs) => {
            if (MyListBox.SelectedIndex < RelevantForms.Length) {
                RelevantForms[MyListBox.SelectedIndex].Show();
                RelevantForms[MyListBox.SelectedIndex].Activate();
            } //if
        };
    } //MyMainForm

    //...

    Form[] RelevantForms;
    // assuming ListBox MyListBox; initialized in InitializeComponent();

} //class MyMainForm


Note: I populate list box with the items of the type System.Type, not strings. It works. The strings presented on screen will be represented using the result of System.Type.ToString.

The form running this initialization is supposed to be a main form. Creating a second instance of this form in the loop is prevented, look at the use of currentType.

—SA
 
Share this answer
 
v4
Comments
Espen Harlinn 12-Jul-11 10:19am    
Nice refinement, my 5
Sergey Alexandrovich Kryukov 12-Jul-11 10:47am    
Thank you, Espen.
--SA
BobJanova 12-Jul-11 10:49am    
This is nice. But why use an array instead of a List<Form>? That way you only need one loop:

foreach (Type type in types) {
if (!type.IsClass) continue;
if (type == currentType) continue;
if (type.IsSubclassOf(typeof(Form)))
Form form = (Form)Activator.CreateInstance(type);
RelevantForms.Add(form);
MyListBox.Items.Add(form);
}
}

Also, it would probably be better to bind the list instead of directly adding entries in this loop.

Edit: By putting the form, instead of the type, in the list, you can just do ((Form)listBox.SelectedItem).Show().
Do the following:

1) Create Form array

C#
Form[] activatedForms = new Form[] { form1, form2, form3... };
You will use this array to index it by the clicked word in the text box.

2) Handle the event ListBox.SelectedItemChanged, find out if the selected item in the right range; if the value greater than activatedForms.Length - 1, do nothing. This index cannot be <0, because by UI you always selecting some item; there is not "unselection".

4) If you found a valid index, activate the form:

C#
activatedForms[index].Activate();


That's it. Have fun. Next time, invent something more practical — just an advice.

See http://msdn.microsoft.com/en-us/library/system.windows.forms.form.aspx[^], http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox.aspx[^].

—SA
 
Share this answer
 
v2
Comments
Tarun.K.S 12-Jul-11 5:06am    
Hi SA, my 5 for the solution. I have answered this in another way. It would be really great if you could have a look at it. Just wanted to hear your suggestion on that method, just for my knowledge only.
OriginalGriff 12-Jul-11 5:26am    
It works - but it's not very obvious, so it is harder to maintain. It doesn't have any mechanism for compile time checking that the referenced form exists, or is an actual form (i.e. derived from the Form class, rather than the Control class, say) and it leaves those checks for run time. Unless your testing regimen makes absolutely sure that all cases are tested, it could leave crash-to-OS bugs in your code for the user to find.
I try to avoid using reflection unless it is really the only way. :laugh:
Tarun.K.S 12-Jul-11 5:48am    
Thanks a lot for the comment. I have added an if-condition to check whether form actually exists or not.
Also 5 to both answers!
Sergey Alexandrovich Kryukov 12-Jul-11 9:37am    
Thank you, Tarun. First, I corrected my answer (I did not read question propertly).
--SA
Tarun.K.S 12-Jul-11 9:42am    
Hi SA, looks fine but did you have a look at my method? It´s quite short and dynamic, uses reflection though.
Here is a dynamic way -

C#
public partial class Form1 : Form
    {
        Assembly currentAssembly;
        Type formType;
        Form form;
        public Form1()
        {
            InitializeComponent();
            this.listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged);
            currentAssembly = Assembly.GetExecutingAssembly();
        }
        void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            formType = currentAssembly.GetType("WindowsFormsApplication1.Form" + listBox1.SelectedItem.ToString());
            if (formType != null)
            {
                form = (Form)Activator.CreateInstance(formType);
                form.Show();
            }
            // Form doesn´t exists
            else
            {
                MessageBox.Show(String.Format("Form {0} doesn't exists",listBox1.SelectedItem.ToString()));
            }
        }
    }


Hope this helps.

Update - Added an if condition to check if form exists or not.

Just to add on, if your listbox had items like -

Form1<br />
MainWindow<br />
HelpWinow<br />

instead of numbers, then using the above method would be much simpler.
just use the below way to define the formType -

C#
formType = currentAssembly.GetType("WindowsFormsApplication1." + listBox1.SelectedItem.ToString());

And the rest will work absolutely perfect.
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 12-Jul-11 9:47am    
I voted 4. Nothing says that a form should be created. Nothing guarantee that a form exists. There is no compile-time detection that this works; only during testing "Form {} doesn't exist". What happens if you decide to renamed some form classes? For this reason, I recommend never find any types of members from by name using reflection. There are other methods.

Also, Form1, ListBox1 violate naming conventions -- always renamed auto-generated names to give it semantic names. Also, anonymous method is better.

Can you do just the opposite? (See my comment below.)
--SA
Sergey Alexandrovich Kryukov 12-Jul-11 10:09am    
However, thanks for the idea. I posted another solution based on modification of your idea. Now I populate list box based on all forms found (except the on running initialization shown, it supposed to be main).

Please see.
--SA
Espen Harlinn 12-Jul-11 10:19am    
Nice idea, my 5
Handle the SelectedIndexChanged event:
private void myListBox_SelectedIndexChanged(object sender, EventArgs e)
    {
    if (myListBox.SelectedIndex >= 0)
        {
        Form f = null;
        switch (myListBox.SelectedIndex)
            {
            case 0:
                f = new Form1();
                break;
            case 1:
                f = new Form2();
                break;
            case 2:
                f = new Form3();
                break;
            case 3:
                f = new Form4();
                break;
            case 4:
                f = new Form5();
                break;
            }
        if (f != null)
            {
            f.Show();
            }
        }
    }
 
Share this answer
 
Comments
kami124 12-Jul-11 4:31am    
thank you ver much i appreciate you.
Tarun.K.S 12-Jul-11 5:06am    
Hi OriginalGriff, I have answered this in another way. It would be really great if you could have a look at it. Just wanted to hear your suggestion on that method, just for my knowledge only.
Sergey Alexandrovich Kryukov 12-Jul-11 9:39am    
I voted 4 just because I cannot agree with such ugly construct as switch here. If you change the set of forms, how to support it? I fixed my solution (did not real question properly), please see.

Creation of forms "new Form"? I don't think it is assumed; in this way you create the again and again. I thought the forms are pre-created. You could lazily created them in this method.

--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900