i have 4 listboxes that are filled with product information. forexample one has the brand and the other the id. when i click on one item in the id the same index of the brand is also clicked. i have a problem regarding the scroll bars. i need to know how to combine the scroll bars with each other forexample when i scroll down the id list then the brand listbox also scrolls down the same number of items. does anyone know how to do this? and if it isnt possible is there any alternative? like having multiple columns in one listbox? but i really need to leave it like this so if u can find a solution then many thanks.

Recommended Answers

All 7 Replies

You can't do it with the normal listbox as it doesn't have a scroll event. So you need to create your own listbox:

using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    public class MyListBox : ListBox {
        public delegate void ScrollEventHandler(Message m);
        public event ScrollEventHandler Scroll;

        protected override void WndProc(ref Message m) {
            if (m.Msg == 0x115 && Scroll != null) Scroll.Invoke(m);
            base.WndProc(ref m);
        }
    }
}

Place this in it's own file, compile and it should be added to your list of controls. Drag/drop them where you need them. Then in your form code you'll need something like this:

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

private void myListBox1_Scroll(Message m) {
    SendMessage(myListBox2.Handle, m.Msg, m.WParam, m.LParam);
}

This will cause myListBox2 to scroll with myListBox1. Don't cross link them as you'll get a stack overflow. To allow that you'll need a sentinel value to indicate that you are scrolling vs the user scrolling.

As for selecting, implement a SelectedIndexChanged handler and select the same index in the listbox that you need changed.

commented: Shows deep knowledge! +9

super many thanks :) it worked perfectly :)

actually it didnt work perfectly... i got a stack overflow error. what did u mean dont cross link them? how do i dont do it? i did this code.

private void lbID_Scroll(Message m)
        {
            SendMessage(lbID.Handle, m.Msg, m.WParam, m.LParam);
        }

        private void lbBrand_Scroll(Message m)
        {
            SendMessage(lbBrand.Handle, m.Msg, m.WParam, m.LParam);
        }

        private void lbModel_Scroll(Message m)
        {
            SendMessage(lbModel.Handle, m.Msg, m.WParam, m.LParam);
        }

        private void lbType_Scroll(Message m)
        {
            SendMessage(lbType.Handle, m.Msg, m.WParam, m.LParam);
        }

        private void lbQuantity_Scroll(Message m)
        {
            SendMessage(lbQuantity.Handle, m.Msg, m.WParam, m.LParam);
        }

        private void lbID_SelectedIndexChanged(object sender, EventArgs e)
        {
            lbModel.SelectedIndex = lbID.SelectedIndex;
            lbBrand.SelectedIndex = lbID.SelectedIndex;
            lbType.SelectedIndex = lbID.SelectedIndex;
            if (lbID.SelectedIndex != -1)
            {
                foreach (Product pro in productList)
                {
                    if ((lbBrand.SelectedItem.ToString().Contains(pro.Brand) && (lbModel.SelectedItem.ToString().Contains(pro.Name))))
                    {
                        pictureBox1.ImageLocation = pro.ImagePath;
                        tbPrice.Text = pro.Price.ToString();
                        tbQtyInStock.Text = pro.Quantity.ToString();
                        break;
                    }
                }
            }
        }

        private void lbBrand_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            lbModel.SelectedIndex = lbBrand.SelectedIndex;
            lbID.SelectedIndex = lbBrand.SelectedIndex;
            lbType.SelectedIndex = lbBrand.SelectedIndex;
            if (lbID.SelectedIndex != -1)
            {
                foreach (Product pro in productList)
                {
                    if ((lbBrand.SelectedItem.ToString().Contains(pro.Brand) && (lbModel.SelectedItem.ToString().Contains(pro.Name))))
                    {
                        pictureBox1.ImageLocation = pro.ImagePath;
                        tbPrice.Text = pro.Price.ToString();
                        tbQtyInStock.Text = pro.Quantity.ToString();
                        break;
                    }
                }
            }
        }

        private void lbModel_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            lbBrand.SelectedIndex = lbModel.SelectedIndex;
            lbID.SelectedIndex = lbModel.SelectedIndex;
            lbType.SelectedIndex = lbModel.SelectedIndex;
            lbQuantity.SelectedIndex = lbModel.SelectedIndex;
            if (lbModel.SelectedIndex != -1)
            {
                foreach (Product pro in productList)
                {
                    if ((lbBrand.SelectedItem.ToString().Contains(pro.Brand) && (lbModel.SelectedItem.ToString().Contains(pro.Name))))
                    {
                        pictureBox1.ImageLocation = pro.ImagePath;
                        tbPrice.Text = pro.Price.ToString();
                        tbQtyInStock.Text = pro.Quantity.ToString();
                        break;
                    }
                }
            }
        }

        private void lbType_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            lbModel.SelectedIndex = lbType.SelectedIndex;
            lbBrand.SelectedIndex = lbType.SelectedIndex;
            lbID.SelectedIndex = lbType.SelectedIndex;
            lbQuantity.SelectedIndex = lbType.SelectedIndex;
            if (lbType.SelectedIndex != -1)
            {
                foreach (Product pro in productList)
                {
                    if ((lbBrand.SelectedItem.ToString().Contains(pro.Brand) && (lbModel.SelectedItem.ToString().Contains(pro.Name))))
                    {
                        pictureBox1.ImageLocation = pro.ImagePath;
                        tbPrice.Text = pro.Price.ToString();
                        tbQtyInStock.Text = pro.Quantity.ToString();
                        break;
                    }
                }
            }
        }

        private void lbQuantity_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            lbModel.SelectedIndex = lbQuantity.SelectedIndex;
            lbBrand.SelectedIndex = lbQuantity.SelectedIndex;
            lbID.SelectedIndex = lbQuantity.SelectedIndex;
            lbType.SelectedIndex = lbQuantity.SelectedIndex;
            if (lbQuantity.SelectedIndex != -1)
            {
                foreach (Product pro in productList)
                {
                    if ((lbBrand.SelectedItem.ToString().Contains(pro.Brand) && (lbModel.SelectedItem.ToString().Contains(pro.Name))))
                    {
                        pictureBox1.ImageLocation = pro.ImagePath;
                        tbPrice.Text = pro.Price.ToString();
                        tbQtyInStock.Text = pro.Quantity.ToString();
                        break;
                    }
                }
            }
        }

apart from this there is what u gavce me too. the class and those 2 lines of code

private void lbID_Scroll(Message m) {
    SendMessage(lbID.Handle, m.Msg, m.WParam, m.LParam);
}

This code says "If I scroll send a message to me that I scrolled". This will continue until you get a stack overflow. You send a message to a different control to tell it to scroll, not the same control. Look at my example.

Same holds true for all your scroll events.

By cross link I mean don't set control1 to tell control2 to scroll and control2 to tell control1 to scroll. They will enter an infinite loop of "I scrolled" messages unless you use a sentinel value to block this kind of behavior..

can i not show the message and just let the user scroll? i want to have those 5 listboxes scroll down at the same time. i tried to make id send to brand, brand to model, model to type, type to quantity, quantity to id but it didnt work either. what should i do to make this work?

You need each control send to all the others, so you'll need a sentinel value so they all don't freak and attempt to scroll each other:

private Boolean userScroll = true;

private void control1_Scroll(Message m) {
    if (userScroll) {
        userScroll = false;
        SendMessage(control2.Handle, m.Msg, m.WParam, m.LParam);
        SendMessage(control3.Handle, m.Msg, m.WParam, m.LParam);
        userScroll = true;
    }
}

private void control2_Scroll(Message m) {
    if (userScroll) {
        userScroll = false;
        SendMessage(control1.Handle, m.Msg, m.WParam, m.LParam);
        SendMessage(control3.Handle, m.Msg, m.WParam, m.LParam);
        userScroll = true;
    }
}

private void control3_Scroll(Message m) {
    if (userScroll) {
        userScroll = false;
        SendMessage(control1.Handle, m.Msg, m.WParam, m.LParam);
        SendMessage(control2.Handle, m.Msg, m.WParam, m.LParam);
        userScroll = true;
    }
}

ok it worked now :) thanks alot.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.