Отображение всплывающей подсказки на нарисованном изображении значка пользовательского элемента управления
Я работал над своим первым настраиваемым пользовательским элементом управления. Пользовательский элемент управления наследует UserControl. Пользовательский элемент управления содержит комбинацию нарисованных прямоугольников, кругов и изображения значка. Я хотел бы отображать всплывающую подсказку, когда пользователь наводит указатель мыши на часть изображения элемента управления. Изображение было создано с помощью drawicon. Затем в моем элементе управления есть событие перемещения мыши, которое определяет, когда мышь находится над значком. Вся эта логика работает правильно. У меня проблема с тем, что после того, как всплывающая подсказка исчезает, она стирает часть элемента управления, над которой зависал. Я пытаюсь выяснить, как правильно перекрасить элемент управления, но мне не повезло.
Что я уже пробовал:
Вот как я рисую контроль:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) Dim rect As System.Drawing.Rectangle = e.ClipRectangle Dim g As Graphics = e.Graphics g.SmoothingMode = SmoothingMode.HighQuality 'Draw the Machine Bed DrawBed(g, rect) 'Draw and position the Machine Head DrawHead(g, rect, _HeadPosInInches) End Sub Private Sub DrawBed(ByVal g As Graphics, ByVal CtlRect As System.Drawing.Rectangle) 'Draws the bed 'Size the bed based on the control size _BedWidth = CInt(CtlRect.Width * _BedWidthFactor) _BedHeight = CInt(CtlRect.Height * _BedHeightFactor) 'Center the bed within the control _BedYBorder = CInt((CtlRect.Height - _BedHeight) / 2) _BedXBorder = CInt(CtlRect.Width - _BedWidth) 'Create a new rect for the bed Dim BedXLoc As Integer = 0 If HeadTravelDir = 1 Then BedXLoc = _BedXBorder Else BedXLoc = 0 End If Dim BedRect As New Rectangle(BedXLoc, _BedYBorder, _BedWidth, _BedHeight) 'Fill the Bed Using Brush1 As New SolidBrush(_BedColor) g.FillRectangle(Brush1, BedRect) End Using 'Create the Bed border Using Pen1 As New Pen(Color.Black, 1) g.DrawRectangle(Pen1, BedRect) End Using End Sub
Вот как я рисую изображение значка на экране:
Dim TargetX As Integer = 0 Dim TargetY As Integer = 0 Dim TargetWidth As Integer = _BedYBorder Dim TargetHeight As Integer = _BedYBorder If _HeadTravelDir = 1 Then TargetX = HeadRect.X + HeadRect.Width + 5 Else TargetX = HeadRect.X - 5 - _BedYBorder End If Dim DashboardIcon As New Icon("U:\photos\DashboardIcons\Question.ico") Dim TargetRect As New Rectangle(TargetX, TargetY, TargetWidth, TargetHeight) IconRect = TargetRect g.DrawIcon(DashboardIcon, TargetRect)
Вот как я обнаруживаю, когда мышь находится над изображением значка:
Private Sub ctlGantry_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove 'Checks to see if the mouse if over the icon If IconRect.Contains(e.Location) Then Debug.WriteLine(e.Location.ToString & " is Over the Icon for " & Me.Name) _IconMouseOver = True 'Me.ToolTip1.Show("test", Me) Else _IconMouseOver = False 'Me.ToolTip1.Hide(Me) 'Me.Invalidate() End If End Sub
Я попытался отобразить всплывающую подсказку как в событиях mousemove, так и в событиях mousehover, но получаю аналогичные результаты. Если я попытаюсь сделать недействительным, когда указатель мыши не находится над значком, я получу сильное мерцание. Фоновый элемент управления также не перерисовывается, когда я перемещаю мышь в другое положение над значком. Я не уверен, связано ли это с той же проблемой, но у меня также есть проблема, когда значок больше не появляется снова после того, как я наведу курсор на элемент управления в течение нескольких секунд, а затем вернусь и вернусь. Если я перекрашу элемент управления и попробую еще раз, всплывающая подсказка появится снова. Я очень близок к тому, чтобы завершить этот элемент управления, но сначала мне нужно это выяснить. Любые идеи?
Graeme_Grant
Вы предоставляете в случае UserControl_Paint [если UserControl является холст] и вызова пользовательских элементов управления.Метод Invalidate () для принудительного перекрашивания при обновлении пользовательского интерфейса?
theskiguy
- Вы правы. См. улучшенный вопрос, который теперь включает в себя некоторый код, показывающий картину элемента управления. Что касается недействительности, то проблема, с которой я сталкиваюсь, заключается в определении подходящего времени для ее вызова. Если я вызываю invalidate только тогда, когда мышь не находится над значком, элемент управления не будет перекрашиваться, если я перемещу мышь в другое положение на значке. Если я перемещаю invalidate в начало события перемещения мыши, мой пользовательский элемент управления полностью исчезает, даже если я перестаю перемещать мышь, когда она находится над значком.
Graeme_Grant
Я не вижу проблемы с кодом, который вы предоставили. Поэтому вместо этого я провел небольшой тест, и все работает так, как ожидалось. Надеюсь, это поможет.