Question: Hello I am working on a project in VB.net that modifies the base .Net canvas class and allows for draggable UI components. All that is
Hello I am working on a project in VB.net that modifies the base .Net canvas class and allows for draggable UI components. All that is left is a snapping feature to help the user line up one component with another. My snapping function works under some strange conditions. If I place a breakpoint anywhere in the mouse up event the function will work after i resume operation of the program. And stranger still that scenario only works if Visual studio is in the same physical screen as the running program. When run on the same screen visual studio minimizes the canvas when it takes focus I was thinking that maybe the objects get redrawn when the canvas is brought back into focus but forcefully triggering a redraw using dispatches or the UpdateDisplay method does not work. I am thouroghly confused what could cause a breakpoint to prevent a function from updating a canvas?
Here is my code that pertains to the snapping feature:
rotected Overrides Sub OnPreviewMouseLeftButtonDown(ByVal e As MouseButtonEventArgs) MyBase.OnPreviewMouseLeftButtonDown(e)
Me.isDragInProgress = False
' Cache the mouse cursor location. Me.origCursorLocation = e.GetPosition(Me)
' Walk up the visual tree from the element that was clicked, ' looking for an element that is a direct child of the Canvas. Me.ElementBeingDragged = Me.FindCanvasChild(TryCast(e.Source, DependencyObject)) If Me.ElementBeingDragged Is Nothing Then Return End If
' Get the element's offsets from the four sides of the Canvas. Dim left As Double = Canvas.GetLeft(Me.ElementBeingDragged) Dim right As Double = Canvas.GetRight(Me.ElementBeingDragged) Dim top As Double = Canvas.GetTop(Me.ElementBeingDragged) Dim bottom As Double = Canvas.GetBottom(Me.ElementBeingDragged)
' Calculate the offset deltas and determine for which sides ' of the Canvas to adjust the offsets. Me.origHorizOffset = ResolveOffset(left, right, Me.modifyLeftOffset) Me.origVertOffset = ResolveOffset(top, bottom, Me.modifyTopOffset)
' Set the Handled flag so that a control being dragged ' does not react to the mouse input. e.Handled = True
Me.isDragInProgress = True End Sub
#End Region
#Region "OnPreviewMouseMove"
Protected Overrides Sub OnPreviewMouseMove(ByVal e As MouseEventArgs) MyBase.OnPreviewMouseMove(e)
' If no element is being dragged, there is nothing to do. If Me.ElementBeingDragged Is Nothing OrElse Not Me.isDragInProgress Then If finishedElement IsNot Nothing Then ' SnapToLine() finishedElement = Nothing End If Return End If
' Get the position of the mouse cursor, relative to the Canvas. Dim cursorLocation As Point = e.GetPosition(Me)
' These values will store the new offsets of the drag element. ' Dim newHorizontalOffset As Double, newVerticalOffset As Double
'#Region "Calculate Offsets"
' Determine the horizontal offset. If Me.modifyLeftOffset Then newHorizontalOffset = Me.origHorizOffset + (cursorLocation.X - Me.origCursorLocation.X) Else newHorizontalOffset = Me.origHorizOffset - (cursorLocation.X - Me.origCursorLocation.X) End If
' Determine the vertical offset. If Me.modifyTopOffset Then newVerticalOffset = Me.origVertOffset + (cursorLocation.Y - Me.origCursorLocation.Y) Else newVerticalOffset = Me.origVertOffset - (cursorLocation.Y - Me.origCursorLocation.Y) End If
AbsoluteCursorLocation = cursorLocation absoluteLocation = VisualTreeHelper.GetOffset(Me.ElementBeingDragged) CheckAlignment(absoluteLocation.X, absoluteLocation.Y) thePropertyChanged("FormattedOffsetString") '#End Region
If Not Me.AllowDragOutOfView Then '#Region "Verify Drag Element Location"
' Get the bounding rect of the drag element. Dim elemRect As Rect = Me.CalculateDragElementRect(newHorizontalOffset, newVerticalOffset)
' ' If the element is being dragged out of the viewable area, ' determine the ideal rect location, so that the element is ' within the edge(s) of the canvas. ' Dim leftAlign As Boolean = elemRect.Left < 0 Dim rightAlign As Boolean = elemRect.Right > Me.ActualWidth
If leftAlign Then newHorizontalOffset = If(modifyLeftOffset, 0, Me.ActualWidth - elemRect.Width) ElseIf rightAlign Then newHorizontalOffset = If(modifyLeftOffset, Me.ActualWidth - elemRect.Width, 0) End If
Dim topAlign As Boolean = elemRect.Top < 0 Dim bottomAlign As Boolean = elemRect.Bottom > Me.ActualHeight
If topAlign Then newVerticalOffset = If(modifyTopOffset, 0, Me.ActualHeight - elemRect.Height) ElseIf bottomAlign Then newVerticalOffset = If(modifyTopOffset, Me.ActualHeight - elemRect.Height, 0)
'#End Region End If End If
'#Region "Move Drag Element"
finishedElement = Me.ElementBeingDragged If Me.modifyLeftOffset Then Canvas.SetLeft(Me.ElementBeingDragged, newHorizontalOffset) Else Canvas.SetRight(Me.ElementBeingDragged, newHorizontalOffset) End If
If Me.modifyTopOffset Then Canvas.SetTop(Me.ElementBeingDragged, newVerticalOffset) Else Canvas.SetBottom(Me.ElementBeingDragged, newVerticalOffset) End If
'SnapToLine() '#End Region End Sub
#End Region
#Region "OnHostPreviewMouseUp"
Protected Overrides Sub OnPreviewMouseUp(ByVal e As MouseButtonEventArgs)
MyBase.OnPreviewMouseUp(e) 'finishedElement = Me.ElementBeingDragged SnapToLine()
'Me.ElementBeingDragged.UpdateLayout() ' Reset the field whether the left or right mouse button was
' released, in case a context menu was opened on the drag element.
Me.ElementBeingDragged = Nothing 'finishedElement = Nothing
End Sub
Private Sub SnapToLine() For Each elem As UIElement In Me.Children If Not IsNothing(elem.Effect) Then Dim deltaX As Double Dim deltaY As Double Try deltaX = VisualTreeHelper.GetOffset(elem).X - VisualTreeHelper.GetOffset(Me.ElementBeingDragged).X deltaY = VisualTreeHelper.GetOffset(elem).Y - VisualTreeHelper.GetOffset(Me.ElementBeingDragged).Y Catch ex As Exception Exit Sub End Try
Dim test1 = Me.ElementBeingDragged.DesiredSize
' Determine horizontal Offset If Me.modifyLeftOffset Then newHorizontalOffset = Me.newHorizontalOffset + deltaX Else newHorizontalOffset = Me.newHorizontalOffset - deltaX End If
' Determine the vertical offset. If Me.modifyTopOffset Then newVerticalOffset = Me.newVerticalOffset + deltaY Else newVerticalOffset = Me.newVerticalOffset - deltaY End If
'Move the Element If Math.Abs(deltaX) < Math.Abs(deltaY) Then If Me.modifyLeftOffset Then Canvas.SetLeft(Me.ElementBeingDragged, newHorizontalOffset) Else Canvas.SetRight(Me.ElementBeingDragged, newHorizontalOffset) End If Else If Me.modifyTopOffset Then Canvas.SetTop(Me.ElementBeingDragged, newVerticalOffset) Else Canvas.SetBottom(Me.ElementBeingDragged, newVerticalOffset) End If End If
End If If Not IsNothing(elem.Effect) Then
elem.Effect = Nothing
End If
Next For Each elem As UIElement In Me.Children
elem.Effect = Nothing Next ' Me.ElementBeingDragged = Nothing End Sub
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
