Как расположить всплывающее меню слева от кнопки?

У меня есть всплывающее меню. Всплывающее меню состоит из двух столбцов. Таким образом, кнопки выровнены по двум столбцам: левому и правому. Внутри него есть кнопки.
При нажатии на одну из кнопок откроется выпадающее меню (созданное с помощью ContextMenuStrip).

Вот так выглядит всплывающее меню и его содержимое:

Как расположить всплывающее меню слева от кнопки?

У меня нет проблем с размещением раскрывающегося меню справа от кнопки «Токен стиля». Проблема возникает, когда я пытаюсь разместить раскрывающееся меню слева от кнопки «Удалить стиль». На изображении ниже показаны примеры:

Выпадающее меню справа от кнопки «Токен стиля» работает просто отлично.

Как расположить всплывающее меню слева от кнопки?

Расположение раскрывающегося списка слева от кнопки «Удалить стиль» проблематично, так как я действительно не знаю, как запрограммировать его логику.
Это должно выглядеть так, как показано ниже:

Как расположить всплывающее меню слева от кнопки?


На самом деле, я закодировал ту часть, с которой у меня возникла проблема. Однако я не совсем уверен, является ли это обычным или профессиональным способом кодирования. Кроме того, иногда между левым выпадающим меню и кнопкой «Удалить стиль» будет случайный зазор.
Ниже показан пример кода:

//--global variable--
int removeStyleStripXPos; //to store xPos of left column dropdown menu

//removeStyleStrip -> the left dropdown menu
//styleTokenStrip -> the right dropdown menu
//--global variable--

//--the mouseUp event handler of "Remove style" button--
private void button13_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        removeStyleStrip.Show(button13, new Point(removeStyleStripXPos, 0));
    }
}

//--the mouseUp event handler of "Style token" button--
private void button14_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        styleTokenStrip.Show(button14, new Point(this.button14.DisplayRectangle.Right, 0));
    }
}

//--the load event handler of the two column popup menu--
private void TCPopupMenuFull_Load(object sender, EventArgs e)
{
    removeStyleStripXPos = -(this.removeStyleStrip.Width);
}

Итак, могу ли я узнать, есть ли лучшие способы установить положение раскрывающегося меню в левом конце кнопки «Удалить стиль»?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Спасибо за время и ответ, @Jimi. Я очень ценю всю вашу помощь.

Он поделился со мной ответом, и это сработало очень хорошо. Оказывается, мне просто нужно настроить логику MouseUp обработчика событий button13, кнопки, которая открывает Remove styleContextMenuStrip.


Коды:

//--the mouseUp event handler of "Remove style" button--
private void button13_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        var screenPos = button13.PointToScreen(Point.Empty);
        removeStyleStrip.Show(new Point(screenPos.X - removeStyleStrip.Width, screenPos.Y));
    }
}

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

Метод Шоу() для ContextMenuStrip (или ToolStripDropDown) имеет перегрузки, которые позволяют указать местоположение на основе либо абсолютных экранных координат, либо координат относительно определенного элемента управления, внутренне преобразованных в экранные координаты относительно поведение, определенного параметром ToolStripDropDownDirection.

// Position the CMS to the absolute right of the Control
SetCMSPosition(someControl, ToolStripDropDownDirection.Right, true);

// Position the CMS to the left of the Control
SetCMSPosition(someControl, ToolStripDropDownDirection.Left, false);

// [...]

private void SetCMSPosition(Control control, ToolStripDropDownDirection direction, bool absolute)
{
    Point location = Point.Empty;
    if (absolute) {
        switch (direction) {
            case ToolStripDropDownDirection.Right:
            case ToolStripDropDownDirection.AboveRight:
                location = new Point(control.ClientSize.Width, 0);
                break;
            case ToolStripDropDownDirection.BelowRight:
                location = new Point(control.ClientSize.Width, control.Height);
                break;
        }
    }
    [The ContextMenuStrip].Show(control, location, direction);
}

Но вы также можете указать координаты экрана, где должен появиться ContextMenuStrip, рассчитав местоположение самостоятельно. Например, слева или справа от элемента управления:
(было бы лучше использовать перечислитель, как и раньше, а не логическое значение)

// Positions the CMS to the right of a Control
SetCMSPosition2(someControl, true);

// Positions the CMS to the left of a Control
SetCMSPosition2(someControl, false);


private void SetCMSPosition2(Control control, bool toTheRight)
{
    Point location = control.PointToScreen(Point.Empty);
    if (toTheRight) {
        location.X += control.ClientSize.Width + 1;
    }
    else {
        location.X -= [The ContextMenuStrip].Width + 1;
    }

    [The ContextMenuStrip].Show(location);
}

Обратите внимание, что в этом случае нет автоматической компенсации для вложенных раскрывающихся элементов управления.

Другие вопросы по теме