Почему мое контекстное меню WinForms не отображается там, где находится мышь? - PullRequest
7 голосов
/ 23 февраля 2011

В моем приложении есть DataGridView, который предназначен для настройки некоторых параметров. Идея состоит в том, что вы можете ввести любой текст в первый столбец, но если щелкнуть правой кнопкой мыши, он предоставит вам явно поддерживаемые значения. Мне нужно, чтобы это было текстовое поле, а не раскрывающийся список, потому что мне нужно поддерживать редактирование неверных (или старых) конфигураций.

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

    private void grvFieldData_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        // If this is a right click on the Field name column, create a context menu 
        //   with recognized options for that field
        if (e.Button == MouseButtons.Right && grvFieldData.Columns[e.ColumnIndex].Name == "clmFieldName")
        {
            ContextMenu menu = new ContextMenu();

            if (_supportedDataGrids.ContainsKey((cmbDataGrid.SelectedItem as DataGridFieldList).GridName))
            {
                // Loop through all the fields and add them to the context menu
                List<string> fields = _supportedDataGrids[((cmbDataGrid.SelectedItem as DataGridFieldList).GridName)];
                fields.Sort();

                foreach (string field in fields)
                    menu.MenuItems.Add(new MenuItem(field));

                // Make sure there is at least one field before displaying the context menu
                if (menu.MenuItems.Count > 0)
                    menu.Show(this, e.Location, LeftRightAlignment.Right);
            }
        }
    }

Это работает "правильно", но контекстное меню появляется в верхней части формы, а не там, где находится указатель мыши. Если я изменю вызов Show() на использование DataGridView вместо формы, у меня возникнет та же проблема, но вместо этого она появится в верхнем левом углу сетки, а не там, где находится мышь.

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

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

Ответы [ 5 ]

19 голосов
/ 23 февраля 2011
 menu.Show(this, e.Location, LeftRightAlignment.Right);

Второй аргумент - это местоположение мыши относительно верхнего левого угла ячейки . Как запрограммировано, вы делаете это смещение относительно этой формы, которая заставит меню появиться в верхнем левом углу формы. Используйте DGV, так как 1-й аргумент тоже не работает, теперь он находится в верхнем левом углу сетки.

Несколько способов исправить это, но это простой способ:

 Point pos = this.PointToClient(Cursor.Position);
 menu.Show(this, pos, LeftRightAlignment.Right);

Вы можете произвольно заменить этот на grvFieldData.

3 голосов
/ 12 июля 2012

В событии щелчка мышью в datagridview:

if e.button= mousebutton.right 
{
   contextmenu1.Show(MousePosition);
}
1 голос
/ 12 ноября 2011

Я решил эту проблему ... этот метод может показаться странным, но он работает отлично!) Если мы хотим видеть контекстное меню, нажимая правую кнопку мыши btn в ячейке таблицы данных, и прямо там, а не в середине экрана или где-то еще, нам нужно:

сделать несколько переменных

int x=0;
int y=0;

сделать событие MouseMove для datagridview1 lke, что:

private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
   x = e.X;
   y = e.Y;
}

и

private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
   if (e.Button == System.Windows.Forms.MouseButtons.Right)
   {
      contextMenuStrip1.Show(dataGridView1, x,y);
   }
}

Добро пожаловать

1 голос
/ 23 февраля 2011

Это не отображается в правильном месте, потому что e.Location - это местоположение относительно верхнего левого угла родительского объекта, который в данном случае является самой ячейкой.Свойства местоположения всегда относительно их контейнера.

Чтобы получить позицию курсора мыши относительно верхнего левого края самой формы, вы можете использовать

this.PointToClient(Cursor.Position);
1 голос
/ 23 февраля 2011

попробуйте использовать PointToClient, чтобы получить правильное место

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...