Получить SourceControl DropDownMenu

У меня есть два события щелчка элементов меню в ContextMenuStrip.
Я могу получить SourceControl выбранного элемента контекстного меню, выполнив этот код:

Control c = ((sender as ToolStripItem).Owner as ContextMenuStrip).SourceControl;

Скриншот пункта контекстного меню

Но когда я использую этот код в элементе контекстного меню, который находится на другом уровне, он возвращает null.

Скриншот пункта контекстного меню на другом уровне

Как я могу получить SourceControl в событии щелчка пункта меню второго снимка экрана?


person GoldErzYT GoldErzYT    schedule 12.11.2018    source источник
comment
Вероятно, проще иметь поле (что-то вроде Control CurrentContextMenuOwner), которое устанавливается при открытии ContextMenu. Подпишитесь на событие Opened() и установите CurrentContextMenuOwner = (sender as ContextMenuStrip).SourceControl;. В любом из ToolStripMenuItems вы можете использовать ссылку CurrentContextMenuOwner для доступа к свойствам элемента управления. Установите для CurrentContextMenuOwner значение null в событиях Closing() или Closed() файла ContextMenu.   -  person Jimi    schedule 12.11.2018
comment
Насколько мне известно, это ошибка в ContextMenuStrip, которая существовала с самого начала. Вы в основном должны делать то, что предложил @Jimi. Вероятно, вы могли бы унаследовать ContextMenuStrip и сделать это внутренне, если хотите, но, если это одноразовый вариант, поле - самый простой вариант.   -  person jmcilhinney    schedule 12.11.2018


Ответы (1)


ContextMenuStrip SourceControl (ссылка на текущий элемент управления, где контекстное меню активирован) можно получить из ToolStripMenuItem, проверив OwnerItem. ссылка и перемещение вверх по течению до тех пор, пока ссылка OwnerItem не станет null, а затем проверка Owner, которое ссылается на ContextMenuStrip.
(К сожалению, ссылка SourceControl доступна только в ContextMenuStrip контроль).

Простой альтернативный метод заключается в использовании Field, который ссылается на Control, где активен текущий ContextMenuStrip (у вас может быть только один активный ContextMenuStrip).
Эта ссылка на поле устанавливается при открытии ContextMenuStrip путем подписки на Opened() — доступ к нему можно получить с помощью любой из ToolStripMenuItem.
Ссылка на поле затем устанавливается обратно на null, когда затем ContextMenuStrip закрывается.

▶ Удаляйте объект contextMenuOwner при закрытии формы.

Пример:
(toolStripMenuItem — это общее имя, оно должно быть установлено как фактическое имя элемента управления).

Control contextMenuOwner = null;

private void toolStripMenuItem_Click(object sender, EventArgs e)
{
    contextMenuOwner?.BackColor = Color.Blue;
    //(...)
}

private void contextMenuStrip1_Opened(object sender, EventArgs e)
{
    contextMenuOwner = (sender as ContextMenuStrip).SourceControl;
}

private void contextMenuStrip1_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
    contextMenuOwner = null;
}
person Jimi    schedule 12.11.2018
comment
Извините, что спрашиваю здесь, но как я могу получить цвет, противоположный цвету? Когда у меня белое, черное наоборот и так далее... - person GoldErzYT GoldErzYT; 12.11.2018
comment
Color OppositeColor = Color.FromArgb(Color.White.ToArgb() ^ 0xffffff); Упрощенный. Противоположный цвет зависит от цвета domain. Это может быть намного сложнее для расчета, в зависимости от пункта назначения. - person Jimi; 12.11.2018