c # перемещать панель по горизонтали с помощью события MouseMove

#c# #winforms

#c# #winforms

Вопрос:

У меня есть приложение winforms. Внутри у меня есть одна панель (panel1), а внутри этой панели другая панель (panel2) с кнопками внутри. Я хочу переместить panel2 по горизонтали внутри panel1 при наведении курсора мыши на какую-либо кнопку. Я сделал это в каждой кнопке внутри panel2.

 this.button4.MouseDown  = new System.Windows.Forms.MouseEventHandler(this.btMouseDown);
        this.button4.MouseMove  = new System.Windows.Forms.MouseEventHandler(this.btMouseMove);
        this.button4.MouseUp  = new System.Windows.Forms.MouseEventHandler(this.btMouseUp);
  

и

 void btMouseMove(object sender, MouseEventArgs e)
    {
        if (_mouseDown)
            panel2.Location = PointToClient(this.panel2.PointToScreen(new Point(e.X - _mousePos.X, e.Y - _mousePos.Y)));            
    }
    void btMouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            _mouseDown = true;
            _mousePos = new Point(e.X, e.Y);
        }
    }
    void btMouseUp(object sender, MouseEventArgs e)
    {
        if (_mouseDown)
        {
            _mouseDown = false;
        }
    }
  

Этот код правильно перемещает panel2 внутри panel1, но я хочу перемещать панель только по горизонтали, и этот код перемещается в местоположение мыши. Я попытался поместить

 Point(e.X - _mousePos.X, 3)
  

Вместо

 Point(e.X - _mousePos.X, e.Y - _mousePos.Y)
  

Но panel2 исчезает. Я хотел бы знать, как переместить panel2 внутри panel1 только по горизонтали.

Большое спасибо.

Комментарии:

1. не работает, панель исчезает: (

2. Что вы на самом деле хотите переместить? Прямо сейчас вы перемещаете panel1, а не panel2.

3. извините, плохая вставка, в моем исходном коде panel1 — это panel2 в этом примере

Ответ №1:

     void btMouseMove(object sender, MouseEventArgs e) {
        if (_mouseDown) {
            int deltaX = e.X - _mousePos.X;
            int deltaY = e.Y - _mousePos.Y;
            panel2.Location = new Point(panel2.Left   deltaX, panel2.Top /*   deltaY */);
        }
    }
  

Ответ №2:

это не самая чистая реализация, но, если я правильно понимаю, что вы пытаетесь сделать, это работает:

         int _x = 0;

    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if(_x == 0)
        {
            _x = e.X;
        }

        int move = 0;
        Point p;

        if (e.X <= _x)
        {
            move = _x - e.X;
            p = new Point(panel2.Location.X - move, panel2.Location.Y);
        }
        else
        {
            move = e.X - _x;
            p = new Point(panel2.Location.X   move, panel2.Location.Y);
        }

        panel2.Location = p;
    }
  

Комментарии:

1. Это тоже интересно и работает нормально, но я все равно предпочитаю первый ответ, спасибо 🙂

Ответ №3:

При перемещении необходимо учитывать текущее местоположение panel2. И вам не нужно преобразовывать местоположение мыши между координатами клиента и экрана, потому что вам нужна только дельта.

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

Например:

 if (delta > 3)  { // only drag if the user moves the mouse over 3 pixels
    panel2.Location = ...
}