Harold Quintero Pineda Ответов: 2

GDI +. не пытайтесь увеличить масштаб положения мыши или панорамирования в первый раз.


Добрый день всем, правда я уже сделал голову к этому, но я не знаю, что делать. Видите ли, я пытаюсь создать элемент управления для рисования с помощью GDI + Engineering graphics (я инженер-строитель), и все шло хорошо, пока не произошло следующее:

* При попытке сделать масштабирование или панорамирование относительно текущего положения мыши, в первый раз, когда я хочу сделать это в элементе управления, это почему-то не удается, так как он всегда делает это относительно (0,0) элемента управления, к которому я делаю преобразование его осей, и его начало у меня находится в левом нижнем углу элемента управления, а с положительной осью Y вверх. Однако после того, как у меня есть первое взаимодействие Zoom (MouseWheel) или Pan (MouseDown и MouseMove), оно творит чудеса.

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

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

Пожалуйста, я ценю, что кто-то может мне помочь.

Да благословит вас Бог.

Что я уже пробовал:

Я попытался проверить в OnPaint, если при выполнении TraslateTransform он (0,0) делает перенос в текущее положение мыши, но все равно это не работает.
Я также пытался изменить порядок масштабирования и Траслейта в краске, но ни то, ни другое.
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        '
        'The current position of the Mouse is obtained.
        Me._mousePositionMove = e.Location

        'Check that you have pressed the left mouse button.
        If e.Button = MouseButtons.Left Then
            '
            'It is verified that there is no saved in the variable, a data
            'which indicates that the mouse has been pressed in the control.
            If Not Me._mousePress = True Then
                '
                'The mouse button was pressed.
                Me._mousePress = True
                '
                'Obtiene las coordenadas del puntero del Mouse cuando se presionó el Mouse.
                Me._mouseDown_Location = e.Location
                'Traslation Old Axis X.
                Me._TraslationX_Graphics_old = Me._TraslationX_Graphics
                'Traslation Old Axis Y.
                Me._TraslationY_Graphics_old = Me._TraslationY_Graphics
                '
                'In this case the drawing is only being adjusted with its Pan and Zoom.
                IsZoomPan_MouseEvent = True

                'I indicate in False the variable that indicates that the drawing fits
                'to the current screen.
                IsFitDrawingToControl_ClikButtonEvent = False

            End If
            '
        End If
        '
        'I also indicate that the reference lines of the Mouse must be drawn.
        LineasReferenciaMouse_Dibujar = True
        '        
        'The control is redrawn in your Paint event.
        Me.Invalidate()
        '
        'Invokes the MouseDown event of the control.
        MyBase.OnMouseDown(e)

    End Sub

phil.o

Можете ли вы хотя бы показать метод, в котором происходит фактическое масштабирование/панорамирование?

2 Ответов

Рейтинг:
2

phil.o

Дикая догадка: вы можете попытаться установить фокус на элемент управления до первого панорамирования/масштабирования.

yourControl.Focus()


Harold Quintero Pineda

Привет, друг. Ничего, не получится.

Я ценю ваш ответ.

Было бы слишком много просить, если бы я послал вам решение Visual Studio и тесты? Поверьте мне, это какая-то мелочь, но я все равно не решаю ее.

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

phil.o

Нет, извините, я бы не согласился получить какой-либо файл. Как я уже сказал в своем комментарии к вашему вопросу, можно ли хотя бы увидеть ту часть, где вы делаете фактический pan/zomm, а также ту, где вы делаете преобразование corrdinates?

Harold Quintero Pineda

Друг, я добавляю код, который ты просишь.

phil.o

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

Harold Quintero Pineda

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

Я думаю, что я не рассматриваю что-то в событии MouseDown и MouseWheel.

Рейтинг:
1

Harold Quintero Pineda

Надеюсь, вы мне поможете.

Событие MouseDown

<pre>  ''' <summary>
    ''' Overwrites the MouseDown event of the base class of the control.
    ''' </summary>
    ''' <param name="e"></param>
    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        '
        'The current position of the Mouse is obtained.
        Me._mousePositionMove = e.Location

        'Check that you have pressed the left mouse button.
        If e.Button = MouseButtons.Left Then
            '
            'It is verified that there is no saved in the variable, a data
            'which indicates that the mouse has been pressed in the control.
            If Not Me._mousePress = True Then
                '
                'The mouse button was pressed.
                Me._mousePress = True
                '
                'Obtiene las coordenadas del puntero del Mouse cuando se presionó el Mouse.
                Me._mouseDown_Location = e.Location
                'Traslation Old Axis X.
                Me._TraslationX_Graphics_old = Me._TraslationX_Graphics
                'Traslation Old Axis Y.
                Me._TraslationY_Graphics_old = Me._TraslationY_Graphics
                '
                'In this case the drawing is only being adjusted with its Pan and Zoom.
                IsZoomPan_MouseEvent = True

                'I indicate in False the variable that indicates that the drawing fits
                'to the current screen.
                IsFitDrawingToControl_ClikButtonEvent = False

            End If
            '
        End If
        '
        'I also indicate that the reference lines of the Mouse must be drawn.
        LineasReferenciaMouse_Dibujar = True
        '        
        'The control is redrawn in your Paint event.
        Me.Invalidate()
        '
        'Invokes the MouseDown event of the control.
        MyBase.OnMouseDown(e)

    End Sub


Событие MouseMove

''' <summary>
''' Overwrites the MouseMove event of the base class of the control.
''' </summary>
''' <param name="e"></param>
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
    '
    'The current position of the Mouse is obtained.
    Me._mousePositionMove = e.Location

    'Check that you have pressed the left mouse button.
    If e.Button = MouseButtons.Left Then
        '
        'Change cursor icon.
         Me.Cursor = Cursors.SizeAll
        '
        'Current position of the mouse pointer
        Dim mousePosNow As PointF = e.Location
        '
        Dim deltaX, deltaY As Single
        deltaX = mousePosNow.X - Me._mouseDown_Location.X
        deltaY = (mousePosNow.Y - Me._mouseDown_Location.Y) * -1 'Change Axis Y sense.

        Me._TraslationX_Graphics = (Me._TraslationX_Graphics_old + (deltaX / Me._zoom))
        Me._TraslationY_Graphics = (Me._TraslationY_Graphics_old + (deltaY / Me._zoom))
        '
        IsZoomPan_MouseEvent = True

        IsFitDrawingToControl_ClikButtonEvent = False

    End If

    LineasReferenciaMouse_Dibujar = True

    Me.Invalidate()

    MyBase.OnMouseMove(e)

End Sub


Эвенто Колесико Мыши.

<pre>    ''' <summary>
    ''' Se produce cuando la rueda del mouse se mueve mientras el control tiene el foco.
    ''' Overwrites the MouseWheel event of the base class of the control.
    ''' </summary>
    ''' <param name="e"></param>
    Protected Overrides Sub OnMouseWheel(e As MouseEventArgs)

        Me._zoom_old = Me._zoom

        If e.Delta > 0 Then
            '
            Me._zoom = Math.Min((Me._zoom + _zoom_increment), _zoom_max)

        Else
            '
            Me._zoom = Math.Max((Me._zoom - _zoom_increment), _zoom_min)

        End If
        '
        Dim mousePosNow As PointF = e.Location
        '
        Dim deltaX, deltaY As Single
        deltaX = mousePosNow.X - 0
        '
        deltaY = Me.ClientRectangle.Height - mousePosNow.Y - 0
        '
        'Variable that save the value considering the zoom immediately
        'previous of the displacements that the Graphics suffered.
        Dim oldGraphicsX As Single
        Dim oldGraphicsY As Single
        oldGraphicsX = ((deltaX / Me._zoom_old))
        oldGraphicsY = ((deltaY / Me._zoom_old))
        '
       'Variable to save the new displacements that the Graphics must suffer,
       'so that the focus center of the Zoom is the current location of the Mouse.
        Dim newGraphicsX As Single
        Dim newGraphicsY As Single
        newGraphicsX = ((deltaX / Me._zoom))
        newGraphicsY = ((deltaY / Me._zoom))
        '
        Me._TraslationX_Graphics = newGraphicsX - oldGraphicsX + Me._TraslationX_Graphics
        Me._TraslationY_Graphics = newGraphicsY - oldGraphicsY + Me._TraslationY_Graphics

        Me._mousePositionMove = mousePosNow
        '
        IsZoomPan_MouseEvent = True
        '
        LineasReferenciaMouse_Dibujar = True

        IsFitDrawingToControl_ClikButtonEvent = False

        Invalidate()
        '
        'Envoca el evento MouseWheel del control.
        MyBase.OnMouseWheel(e)

    End Sub


Событие Paint

    ''' <summary>
    ''' Overwrites the Paint event of the base class of the control.
    ''' </summary>
    ''' <param name="e"></param>
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        '
        Me._graphicsControl = e.Graphics
        '
        Me._graphicsControl.Clear(GraphicsControl_ClearColor)

        Me._graphicsControl.SmoothingMode = If(Me.GraphicsControl_CalidadDibujo = SmoothingMode.Invalid, SmoothingMode.AntiAlias, Me.     GraphicsControl_CalidadDibujo)
        '
        'I check if the user has decided to draw the axes of reference X-Y
        'in the bottom left corner of the control.
        If Me.EjesGlobales_Dibujar = True Then
            '
            Transforms the axes of the graph with its origin in the lower left part of the control and with   the AXIS pointing  upwards (positive)
            TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)
            '
            'I call the event in charge of drawing the X-Y axes.
            Me.DibujarEjesControl()
            '
        End If

        '
        'I check if the user has decided to draw the reference lines of the Mousecontrol.
        If Me.LineasReferenciaMouse_Dibujar = True Then
            '
             TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)
            '
            Me._graphicsControl.ScaleTransform(Me._zoom, _zoom)
            '
            Me._graphicsControl.TranslateTransform(Me._TraslationX_Graphics, Me._TraslationY_Graphics)
            '
             DibujarLineasReferenciaMouse(Me._mousePositionMove, Me._graphicsControl)
            '
        End If

        'A new instance of the Zapata Class is created.
        Dim myzapata As New MyDrawings.ZapataPlanta(2.5D, 3.5D, e.Graphics) With {
            .Contorno_Color = Color.DarkRed,
            .Contorno_GrosorPen = 0.8D,
            .Relleno_Color = Color.DarkBlue,
            .Relleno_ColorTransparencia = 25
        }

        Dim myPath As GraphicsPath = myzapata.GraphicsPath_Dibujo

        Dim myPointsAll As PointF() = myPath.PathPoints

       'Center of the customer area or the control needed to center the drawing on the screenla.
        Dim centerControl As New PointF With {
            .X = (ClientRectangle.Left + ClientRectangle.Right) / 2.0F,
            .Y = (ClientRectangle.Bottom + ClientRectangle.Top) / 2.0F
        }

'        'First, I verify that the drawing you want to make in the Graphics
         'want to adjust to the current size of the control and in the center of it.
        If Me.IsFitDrawingToControl_ClikButtonEvent = True Then

            TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)

            'The coordinates of the World are transformed, for which the Graphics previously has a matrix of Transformation
             'to coordinates of the page, the points that my drawing contains or Path to show.
            _graphicsControl.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, myPointsAll)

            'Drawing on the X axis and Y, Centro is obtained with the sum of the minimum and maximum coordinate in the
             'axis, divided between two. These coordinates are already converted to page coordinates.
            Dim centerDibujo As New PointF With {
                .X = (myPointsAll.Min(Function(x) x.X) + myPointsAll.Max(Function(x) x.X)) / 2.0F,
                .Y = (myPointsAll.Min(Function(y) y.Y) + myPointsAll.Max(Function(y) y.Y)) / 2.0F
            }

             _graphicsControl.TranslateTransform(-centerDibujo.X, -centerDibujo.Y, MatrixOrder.Append)

            Dim scaleRatioPage As Single
            scaleRatioPage = Math.Min((ClientRectangle.Width - 30) / myPath.GetBounds.Width, (ClientRectangle.Height - 30) / myPath.GetBounds.Height)

        
            _graphicsControl.ScaleTransform(scaleRatioPage, scaleRatioPage, MatrixOrder.Append)


            _graphicsControl.TranslateTransform(centerControl.X, centerControl.Y, MatrixOrder.Append)

      
            _graphicsControl.FillPath(myzapata.Brush_RellenoZapata, myPath)
            _graphicsControl.DrawPath(myzapata.Pen_ContornoZapata(CDec(scaleRatioPage)), myPath)

            '
             'If the user is using Mouse events, he means
             'who is wanting to make Zoom or Pan.
        ElseIf Me.IsZoomPan_MouseEvent = True Then

            '
             TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)

            Dim scaleRatioPage As Single
            scaleRatioPage = Math.Min((ClientRectangle.Width - 30) / myPath.GetBounds.Width, (ClientRectangle.Height - 30) / myPath.GetBounds.Height)

            _graphicsControl.TranslateT


phil.o

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

Harold Quintero Pineda

Большое вам спасибо за вашу признательность партнеру.

Я знаю, что ошибка находится в MouseDown, потому что переменные _TraslationX_Graphics и _TraslationY_Graphics, всегда по умолчанию, равны нулю (0). Затем, при нажатии кнопки ButtonLeft в MouseDown, то, что он делает, заключается в том, что рисунок запускается в начало координат (0,0), только насколько я взаимодействую с рисунком в первый раз, но позже, если он работает.

Теперь, как я мог принять это условие во внимание в том событии MouseDown?

phil.o

Сейчас уже поздно, я посмотрю это завтра утром.
Любезно.

Harold Quintero Pineda

Великолепно, спасибо за ваш энтузиазм в помощи мне, я действительно очень благодарен.
Спокойной ночи.

phil.o

Вы пробовали поместить точку останова в обработчик событий mouse down? Вы говорите, что переменные имеют нулевое значение по умолчанию; чему они должны равняться вместо этого? Может быть, попытаться инициализировать их в центр управления (control.Ширина / 2, Контроль.высота / 2). Это позволило бы начать с начала панорамирования/масштабирования по умолчанию в центре элемента управления, а не на краю.

Harold Quintero Pineda

Друг, это проблема как MouseDown, так и MouseWheel, чтобы иметь первое взаимодействие с событиями мыши. Я попробовал то, что он сказал, но даже если он изменит источник передачи в первый раз, у него все равно будет странное поведение, когда он начнет.

Я знаю, что в первый раз, когда пользователь масштабирует (колесо мыши) или панорамирует (MouseDown и MouseMove), я должен определить значения так, чтобы рисунок (всегда при запуске настраивается на размер элемента управления и центрируется) перемещался или масштабировался в соответствии с этим положением мыши, но я не могу этого сделать. Я запустил переменные с позиции мыши, также в центре элемента управления, но это все равно не работает.

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

Пожалуйста, умоляю вас, помогите мне.