0

I have listbox with some items in it, what I'm looking for this:

always previous items keep selected and if i click an item that isn't selected it get selected too but if it's already selected it get's unselected. I used these code but it doesn't work very well! here's my code(this one does not work at all):

public partial class Options_Form : Form
{
    public Options_Form()
    {
        InitializeComponent();
    }

    private void Options_Load(object sender, EventArgs e)
    {
        AceMP_Class cl = new AceMP_Class();
        listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
        listBox1.SelectionMode = SelectionMode.MultiExtended;
        listBox1.Size = listBox1.PreferredSize;
        listboxitemsState_array = new bool[cl.SupportedFiles_stringarray().Length];
    }

    private void button2_Click(object sender, EventArgs e)
    {
        listBox1.ClearSelected();
        //selecteditemsindex_list.Clear();
    }

    //List<int> selecteditemsindex_list = new List<int>();

    bool[] listboxitemsState_array;

    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        for (int i = 0; i < listboxitemsState_array.Length; i++)
        {
            if (listboxitemsState_array[i])
            {
                listBox1.SetSelected(i, true);
            }
            else
            {
                listBox1.SetSelected(i, false);
            }
        }

        //if (listBox1.GetSelected(listBox1.IndexFromPoint(e.X, e.Y)))
        if (listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)])
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), false);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = false;
        }
        else
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), true);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = true;
        }

    }

    private void listBox1_MouseUp(object sender, MouseEventArgs e)
    {

        for (int i = 0; i < listboxitemsState_array.Length; i++)
        {
            if (listboxitemsState_array[i])
            {
                listBox1.SetSelected(i, true);
            }
            else
            {
                listBox1.SetSelected(i, false);
            }
        }

        //if (listBox1.GetSelected(listBox1.IndexFromPoint(e.X, e.Y)))
        if (listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)])
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), false);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = false;
        }
        else
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), true);
            listboxitemsState_array[listBox1.IndexFromPoint(e.X, e.Y)] = true;
        }

    }

}

but this one works but not very well!

public partial class Options_Form : Form
{
    public Options_Form()
    {
        InitializeComponent();
    }

    private void Options_Load(object sender, EventArgs e)
    {
        AceMP_Class cl = new AceMP_Class();
        listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
        listBox1.SelectionMode = SelectionMode.MultiExtended;
        listBox1.Size = listBox1.PreferredSize;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        listBox1.ClearSelected();
        selecteditemsindex_list.Clear();
    }

    List<int> selecteditemsindex_list = new List<int>();

    private void listBox1_Click(object sender, EventArgs e)
    {
        listBox1.ClearSelected();
    }

    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        for (int i = 0; i < selecteditemsindex_list.Count; i++)
        {
            listBox1.SetSelected(selecteditemsindex_list[i], true);
        }
    }

    private void listBox1_MouseUp(object sender, MouseEventArgs e)
    {

        for (int i = 0; i < selecteditemsindex_list.Count; i++)
        {
            listBox1.SetSelected(selecteditemsindex_list[i], true);
        }
        if (listBox1.GetSelected(listBox1.IndexFromPoint(e.X, e.Y)))
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), false);
        }
        else
        {
            listBox1.SetSelected(listBox1.IndexFromPoint(e.X, e.Y), true);
            selecteditemsindex_list.Add(listBox1.IndexFromPoint(e.X, e.Y));
        }
    }

}

How can I solve that!?

ACE
  • 379
  • 3
  • 12

2 Answers2

1

I want to mention that you achieved this feature with SelectionMode.MultiExtended but you need to press CTRL + Click or SHIFT + Click.

To achieve this only with mouse:

1) A better solution comes up as when i discuss with @ACE (he come up with idea to use virtualkey) is to press CTRL key when you make clicks. On MouseDown you press CTRL and on MouseUp release the CTRL key.

public partial class Options_Form : Form
{
    public Options_Form()
    {
        InitializeComponent();
    }

    private void Options_Load(object sender, EventArgs e)
    {
        AceMP_Class cl = new AceMP_Class();
        listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
        listBox1.SelectionMode = SelectionMode.MultiSimple;
        listBox1.Size = listBox1.PreferredSize;
    }

    [DllImport("user32.dll", SetLastError = true)]
    static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

    public const uint KEYEVENTF_KEYUP = 0x02;
    public const uint VK_CONTROL = 0x11;

    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        keybd_event(Convert.ToByte(VK_CONTROL), 0, 0, 0);
    }

    private void listBox1_MouseUp(object sender, MouseEventArgs e)
    {
        keybd_event(Convert.ToByte(VK_CONTROL), 0, Convert.ToByte(KEYEVENTF_KEYUP), 0);
    }
}

2) The easiest solution that comes up in my mind (with some drawbacks if you pres click very fast) is to use on MouseClick event and to have an array of bool that every index from that array tells me if selected or not.

selecteditemsindex_list[selectedIndex] = !selecteditemsindex_list[selectedIndex];

How it works?

Take the current index and negate (!) the value at that index. This way you obtain select/unselect feature with mouse.

Because i work only with the current index the others values from array remains unmodified and i can use SetSelected for all values from array. This way you can make multiselect with mouse.

public partial class Options_Form : Form
{
    public Options_Form()
    {
        InitializeComponent();
    }
    bool[] selecteditemsindex_list;

    private void Options_Load(object sender, EventArgs e)
    {
        AceMP_Class cl = new AceMP_Class();
        listBox1.Items.AddRange(cl.SupportedFiles_stringarray());
        listBox1.SelectionMode = SelectionMode.MultiExtended;
        listBox1.Size = listBox1.PreferredSize;
        selecteditemsindex_list = new bool[listBox1.Items.Count];
    }

    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        var selectedIndex = listBox1.SelectedIndex;
        selecteditemsindex_list[selectedIndex] = !selecteditemsindex_list[selectedIndex];
        for (int i = 0; i < selecteditemsindex_list.Count(); i++)
        {
            listBox1.SetSelected(i, selecteditemsindex_list[i]);
        }
    }
}
Community
  • 1
  • 1
adricadar
  • 9,971
  • 5
  • 33
  • 46
  • Thanks for your answer :) I'm gonna try it and inform you – ACE Mar 26 '15 at 14:05
  • Do you know why someone DownVoted my question!? – ACE Mar 26 '15 at 14:06
  • error on second item selecting :( for this line: selecteditemsindex_list[selectedIndex] = !selecteditemsindex_list[selectedIndex]; Error: Index was outside the bounds of the array. – ACE Mar 26 '15 at 15:02
  • & yeah Actually I want to do exactly Ctrl key operation but just click without holding ctrl key! – ACE Mar 26 '15 at 15:04
  • yeah it's initialized! I think it would help: listBox1.SelectedIndex -1 int selectedIndex -1 int these are the values when error occured – ACE Mar 26 '15 at 15:08
  • sorry I don't understand what you mean! – ACE Mar 26 '15 at 15:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/73861/discussion-between-ace-and-adricadar). – ACE Mar 26 '15 at 15:13
0

The ListBox control has a property 'SelectionMode' You can set it to :

  1. One
  2. MultiSimple
  3. MultiExtended

see this link for details