TheRuudster Ответов: 2

Как повернуть сгенерированные элементы управления в VB.NET-что?


Привет,

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

Проблема:
Когда я поворачиваю сгенерированный picturebox с помощью rightmousebutton, ничего не происходит. Хотя это должно сработать, верно?. Однако если я нажму rightmousebutton, а затем нажму leftmousebutton и начну перетаскивать элемент управления, то он сразу же вращается.

Кто-нибудь знает, что я сделал не так и как я мог бы это исправить?

Примечание: изображения должны вращаться только под углом 90 градусов

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

Вот код, в котором элементы управления добавляются во время выполнения и все обработчики событий для его перемещения и получения информации. Drawinggrid является родителем элемента управления PictureBox, где элементы управления добавляются на.

Private Sub DrawingGrid_DoubleClick(sender As Object, e As MouseEventArgs) Handles DrawingGrid.DoubleClick
      item_num = 0
      Dim pic As New TransparentPicturebox With
      {
      .Visible = True,
      .Size = New System.Drawing.Size(ItemResizeTrackBar.Value, ItemResizeTrackBar.Value),
      .SizeMode = PictureBoxSizeMode.StretchImage,
      .BackColor = Color.Transparent,
      .Image = ImageSelect(),
      .Tag = index & "." & item_num,
      .Text = curr_item
      }

      DrawingGrid.Controls.Add(pic)

      If picnum > 0 Then
          For k As Integer = 0 To picarray.Length - 1
              If picarray(k).Text = pic.Text Then
                  item_num = item_num + 1
              End If
              pic.Tag = index & "." & item_num
          Next
      End If

      Dim i As ListViewItem
      i = Changelog.Items.Add("")
      i.SubItems.Add(pic.Tag)
      i.SubItems.Add(pic.Text & " Added")
      i.SubItems.Add("Size: (" & pic.Size.Height & ";" & pic.Size.Width & ")")
      Changelog.Items((Changelog.Items.Count - 1)).EnsureVisible()

      Dim picList As List(Of TransparentPicturebox) = New List(Of TransparentPicturebox)
      For Each c As TransparentPicturebox In DrawingGrid.Controls
          If (TypeOf c Is TransparentPicturebox) Then
              picList.Add(DirectCast(c, TransparentPicturebox))
          End If
      Next
      picarray = picList.ToArray

      pic.Location = New Point(MousePosition.X - DrawingGrid.Location.X - ItemResizeTrackBar.Value / 2, MousePosition.Y - DrawingGrid.Location.Y - 24 - ItemResizeTrackBar.Value / 2)

      If picnum > 0 Then
          TextBox1.Text = Math.Round(Math.Sqrt(Math.Abs(picarray(picnum).Location.X - picarray(picnum - 1).Location.X) ^ 2 + (Math.Abs(picarray(picnum).Location.Y - picarray(picnum - 1).Location.Y) ^ 2)))
      End If

      AddHandler pic.MouseDown, AddressOf PictureboxMouseDown
      AddHandler pic.MouseUp, AddressOf PictureboxMouseUp
      AddHandler pic.MouseMove, AddressOf PictureboxMouseMove
      'AddHandler pic.MouseWheel, AddressOf PictureboxMouseWheel
      AddHandler pic.Click, AddressOf PictureboxMouseClick

      picnum = picnum + 1
  End Sub
  'imageselect function




  Private Function ImageSelect()
      Dim SelectImageToPlaceFromDatabase_Adapter As New OleDbDataAdapter("SELECT Id, Naam, Locatie FROM onderdelen WHERE Id =" & index + 1, myconnection)
      Dim dq As New DataSet()
      myconnection.Open()
      SelectImageToPlaceFromDatabase_Adapter.Fill(dq, "onderdelen")
      myconnection.Close()

      curr_item = dq.Tables(0).Rows(0).Item(1)

      Return Image.FromFile(dq.Tables(0).Rows(0).Item(2))
  End Function



  'PIC EVENT HANDLERS
  'mouse down event update current data
  Private Sub PictureboxMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
      Dim pic As TransparentPicturebox = CType(sender, TransparentPicturebox)
      curr_item = pic.Text
      move_object = e.Location
  End Sub


  'moving the pic
  Private Sub PictureboxMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
      Dim pic As TransparentPicturebox = CType(sender, TransparentPicturebox)
      PositionStatus.Text = "Position: " & pic.Location.ToString

      If (e.Button = MouseButtons.Left) Then
          pic.Left = (pic.Left + (e.X - move_object.X))
          pic.Top = (pic.Top + (e.Y - move_object.Y))

          If picnum > 1 Then
              TextBox1.Text = Math.Round(Math.Sqrt(Math.Abs(picarray(picnum - 1).Location.X - picarray(picnum - 2).Location.X) ^ 2 + (Math.Abs(picarray(picnum - 1).Location.Y - picarray(picnum - 2).Location.Y) ^ 2)))
          End If
      End If
      If DrawingGrid.Height <= (pic.Height + pic.Location.Y) Then
          pic.Top = DrawingGrid.Height - pic.Height
          If pic.Location.X <= 0 Then
              pic.Left = 0
          ElseIf DrawingGrid.Width <= (pic.Width + pic.Location.X) Then
              pic.Left = DrawingGrid.Width - pic.Width
          End If
      ElseIf pic.Location.Y <= 0 Then
          pic.Top = 0
          If pic.Location.X <= 0 Then
              pic.Left = 0
          ElseIf DrawingGrid.Width <= (pic.Width + pic.Location.X) Then
              pic.Left = DrawingGrid.Width - pic.Width
          End If
      ElseIf pic.Location.X <= 0 Then
          pic.Left = 0
      ElseIf DrawingGrid.Width <= (pic.Width + pic.Location.X) Then
          pic.Left = DrawingGrid.Width - pic.Width
      End If

  End Sub


  'add movement changes to changelog
  Private Sub PictureboxMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
      Dim pic As TransparentPicturebox = CType(sender, TransparentPicturebox)
      Dim i As ListViewItem
      i = Changelog.Items.Add("")
      i.SubItems.Add(pic.Tag)
      i.SubItems.Add(pic.Text & " Moved to")
      i.SubItems.Add("Location: (" & pic.Location.X & ";" & pic.Location.Y & ")")
      Changelog.Items((Changelog.Items.Count - 1)).EnsureVisible()
  End Sub


  'middle click info & right click rotate event
  Private Sub PictureboxMouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
      Dim pic As TransparentPicturebox = CType(sender, TransparentPicturebox)
      Select Case e.Button
          Case MouseButtons.Middle
              'MessageBox.Show("Item: " & curr_item)
              Dim Info As New Form
              Info.Show()
              TextBox1.Text = e.Location.ToString
              Info.Top = MousePosition.Y
              Info.Left = MousePosition.X
              Info.Height = 250
              Info.Width = 250
              Info.Text = "Info"
              Info.MinimizeBox = False
              Info.MaximizeBox = False
              Info.ShowIcon = False
              Info.Opacity = 0.92
              Info.MaximumSize = Info.Size
              Info.MinimumSize = Info.Size

              AddHandler Info.Deactivate, AddressOf Info_Deactivate

              Dim lbl As New Label With
              {
              .Text = pic.Tag,
              .Location = New Point(100, 100)
              }

              Dim lblUp As New Label With
              {
              .Image = My.Resources.About,
              .Location = New Point(0, 0)
              }

              AddHandler lblUp.Click, AddressOf lblUp_Click

              Info.Controls.Add(lblUp)
              Info.Controls.Add(lbl)
          Case MouseButtons.Right
              pic.Image.RotateFlip(RotateFlipType.Rotate90FlipNone)
      End Select
  End Sub

2 Ответов

Рейтинг:
16

OriginalGriff

Попробуйте сделать недействительным picturebox:

Case MouseButtons.Right
    pic.Image.RotateFlip(RotateFlipType.Rotate90FlipNone)
    pic.Invalidate()


TheRuudster

Большое вам спасибо! Совсем забыл это сделать ха ха

OriginalGriff

Легко сделать! :смеяться:

Рейтинг:
10

Jochen Arndt

pic.Image.RotateFlip(RotateFlipType.Rotate90FlipNone)
будет вращать изображение, но не обновлять его. PictureBox потому что он использует Get метод.

Признать недействительным PictureBox чтобы вызвать перерисовку:
pic.Image.RotateFlip(RotateFlipType.Rotate90FlipNone)
pic.Invalidate()
Используйте аннулирование, а не Refresh здесь потому, что операция выполняется внутри обработчика.


TheRuudster

Спасибо!

Jochen Arndt

Добро пожаловать.
Спасибо, что согласились даже с решением, подобным решению 1. Но когда я начал отвечать, решения пока не было.