none
При использовании toolStripMenuItem с listBox никак не могу определить выбранный элемент. RRS feed

  • Вопрос

  • Извините, где-то в форуме видел ответ, а сейчас никак не могу найти . С TreeView вопрос решил. Там использую событие NodeMouseClick

    и его аргумент TreeNodeMouseClickEventArgs e   .  Ясно, что и с  listBox   должен быть аргумент некоторого события, но какой аргумент и какого события?

    Помогите, пожалуйста

Ответы

  • Вам нужно использовать событие MouseDown вашего ListBox или переопределить метод OnMouseDown. Тогда пример который я привел в предыдущем сообщении будет работать как вы хотите.
            private void listBox1_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    ((ListBox)sender).SelectedIndex = ((ListBox)sender).IndexFromPoint(e.Location);                
                }     
            }

    • Предложено в качестве ответа Abolmasov Dmitry 7 мая 2013 г. 6:59
    • Помечено в качестве ответа Miklv 7 мая 2013 г. 11:18
  • Miklv, для того, чтобы получить индекс элемента вам не нужно самостоятельно рассчитывать его расположение, используя ItemHeight. Применяйте метод IndexFromPoint, как ответил вам Bazzzy и как приведено в примере, в моем сообщении выше. Даже при скролинге, этот метод вернет вам правильный индекс.
    • Предложено в качестве ответа Abolmasov Dmitry 7 мая 2013 г. 6:59
    • Помечено в качестве ответа Miklv 7 мая 2013 г. 11:18

Все ответы

  • А если вы используете не мышь а клавиатуру для выделения нода? Для TreeView  есть свойство SelectedNode. Для ListBox используйте свойства SelectedItem и SelectedItems.
  • Спасибо, но это очень неизящно, Тем более, что выделить текущий можно левой кнопкой мыши. Представляете, Вы кликаете левой кнопкой мыши(или стрелками клавиатуры), а потом кликаете правой кнопкой для открытия контексного меню.  Разработчики предусмотрели в свойствах ListBox возможность задать ContextMenuStrip, Но задание этого параметра безсмысленно без возможности получить выбранный правой кнопкой элемент.

    Логично, если бы нужное событие было MouseClick, но в передаваемых аргументах я не нашел указания на выбранный элемент. Что-то я делаю не так, а что никак не пойму.

  • На этот раз, я кажется понял что вам нужно. У вас есть ListBox и для него задан ContextMenuStrip. Поймите что ContextMenuStrip понятия не имеет про то к контролу какого типа он привязан, в противном случае представьте количество различных сценариев которые должны были предусмотреть разработчики, ему собственно это совсем и не нужно. Вот пример того как вы можете реализвать то что вам нужно (не забудьте подписаться на ивент ItemCLicked):

            private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
            {            
                this.Text = ((ListBox)((ContextMenuStrip)sender).SourceControl).SelectedItem.ToString() + e.ClickedItem.Text;
            }

    и то что SelectedItem может быть null тоже не забывайте )

  • Используя свойство Location класса MouseEventArgs можно получить индекс элемента ListBox, а так же из свойства Button узнать какая кнопка мыши была нажата. Далее можете обработать событие Opening класса ContextMenuStrip, если содержание вашего контекстного меню зависит от выбранного элемента (посмотрите пример)


  • Большое спасибо за внимание, проявленное к моему вопросу. Извините за неполную формулировку вопроса.

    Я хочу использовать  toolStripMenuItem для выполнения некоторых операций над Item ListBox на котором кликнули правой мышкой и выбрали соответвующий пункт меню, например переименовать или удалить.  Сам элемент просто объект и не обладает событиями. Мы ловим события его владельца и моя задача через них идентифицировать нужный элемент.

    В ответе Bazzzy выражение ((ListBox)((ContextMenuStrip)sender).SourceControl) идентифицирует ListBox в котором произошло событие, но не элемент нт, а SelectedItem - элемент выбранный другим действием и мы не можем на него полагаться, так как пользователь нашей  программы может выбрать один элемент, а кликнуть правой мышкой на другом (клик правой мышкой не меняет текущего элемента), а e.ClickedItem определяет строку меню, которую мы выбрали, а не элемент в ListBox

    Подход Dmitriy__ более конструктивен, он позволяет получить координаты клика мышки и зная высоту элемента (через ItemHeight) о можно найти индекс выбранного элемента если нет скрулинга. Но что делать, если есть скрулинг. Через какокой доступный параметр получить поправку?

    Или я что-то неправильно понял?

    Извините, небольшая подсказка (пояснение) для тех, кто еще не пользуется  toolStripMenuItem . Для применения  toolStripMenuItem  нужно использовать не менее двух событий. в одном мы определяем что была нажата правая кнопка мыши и запоминаем параметры нажатия, а в другом обрабатываем выбор конкретной строки меню и там используем запомненные параметры. При использовании TreeView есть очень удобное событие

    NodeMouseClick в котором можно получить узел, на котором кликнули правой мышкой. Для ListBox такого хорошего события нет. При использовании toolStripMenuItem нажатие правой кнопки мыши не обрабатывается MouseClick и надо применять MouseDown

  • Вам нужно использовать событие MouseDown вашего ListBox или переопределить метод OnMouseDown. Тогда пример который я привел в предыдущем сообщении будет работать как вы хотите.
            private void listBox1_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    ((ListBox)sender).SelectedIndex = ((ListBox)sender).IndexFromPoint(e.Location);                
                }     
            }

    • Предложено в качестве ответа Abolmasov Dmitry 7 мая 2013 г. 6:59
    • Помечено в качестве ответа Miklv 7 мая 2013 г. 11:18
  • Miklv, для того, чтобы получить индекс элемента вам не нужно самостоятельно рассчитывать его расположение, используя ItemHeight. Применяйте метод IndexFromPoint, как ответил вам Bazzzy и как приведено в примере, в моем сообщении выше. Даже при скролинге, этот метод вернет вам правильный индекс.
    • Предложено в качестве ответа Abolmasov Dmitry 7 мая 2013 г. 6:59
    • Помечено в качестве ответа Miklv 7 мая 2013 г. 11:18
  • Большое спасибо Dmitriy__  и Bazzzy. Вы оказали мне  существенную помощь. Все работает