Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
1285
Problem with dragging chart shapes
posted

Hi

I am trying to convert an OrgChart program I wrote for Silverlight v12.1 to WPF4 v15.2.

Just about everything works fine - the only issue I have is that in dragging a chart shape from one node to another there is no visible drag taking place. The drag however does work and the shape does move from one node to another - its just that the user has no idea what is being dragged.

I have looked through the samples and I am not using any drag template (this was not needed in SL v12.1) so this may be the issue. If this is the case do you have an example of creating a drag template at runtime in code (not xaml)?

If it helps my code is shown below

With thanks

Andrew Hunot


Private OrganizationModel As New OrganizationViewModel()

Public Sub New()

' This call is required by the designer.
InitializeComponent()

' Add any initialization after the InitializeComponent() call.

End Sub

Public Function CreateChart(ByVal sXML As String) As Boolean

Me.OrganizationModel.Employees = New ObservableCollection(Of Employee)()

Try

Dim xd As XDocument
xd = XDocument.Parse(sXML)

For Each xe As XElement In xd.Nodes
If xe.Name = "EmployeeData" Then
For Each xf As XElement In xe.Nodes
If xf.Name = "Employees" Then
Dim NewEmployee As New Employee
CreateNodes(xf.Nodes, NewEmployee)
Me.OrganizationModel.Employees.Add(NewEmployee)
End If
Next
End If
Next

Catch ex As Exception

Debug.Print(ex.Message)

Return False

End Try

Me.OrgChart.DataContext = Me.OrganizationModel

Return True

End Function

Public Sub SetScaleToFit()

Me.OrgChart.ScaleToFit()

End Sub

Private Sub CreateNodes(ByVal nodes As Object, ByRef ThisEmployee As Employee)

ThisEmployee.Subordinates = New ObservableCollection(Of Employee)

For Each xe As XElement In nodes

If xe.Name = "EmpID" Then
ThisEmployee.Id = xe.Value
End If
If xe.Name = "EmpName" Then
ThisEmployee.Name = xe.Value
End If
If xe.Name = "EmpAttr" Then
ThisEmployee.Attributes = xe.Value
End If

If xe.Name = "Employees" Then
Dim NewEmployee As New Employee
CreateNodes(xe.Nodes, NewEmployee)
ThisEmployee.Subordinates.Add(NewEmployee)
End If

Next

End Sub

Private Sub OrgChart_NodeControlAttachedEvent(sender As Object, e As OrgChartNodeEventArgs)

Dim employee As Employee = DirectCast(e.Node.Node.Data, Employee)
If employee.Attributes <> "" Then e.Node.Background = New SolidColorBrush(ColorConverter.FromString(employee.Attributes))

'Create a new DragSource object.
Dim dragSource As New DragSource()
dragSource.IsDraggable = True 'dragSource.DragChannels = assign drag channels
AddHandler dragSource.Drop, AddressOf Node_Drop

'Make the Node a Drag Source.
DragDropManager.SetDragSource(e.Node, dragSource)

'Create a new DropTarget object.
Dim dropTarget As New DropTarget()
dropTarget.IsDropTarget = True 'dropTarget.DropChannels = assign drop channels

'Make the Node a Drop Target.
DragDropManager.SetDropTarget(e.Node, dropTarget)

End Sub

Private Sub Node_Drop(sender As Object, e As DropEventArgs)

Dim DropOnNode As Boolean = False

'Get the dragged OrgChartNodeControl object.
Dim draggedNodeControl As OrgChartNodeControl = TryCast(e.DragSource, OrgChartNodeControl)
'Get the dragged OrgChartNode object.
Dim draggedNode As OrgChartNode = draggedNodeControl.Node
'Get the underlying data.
Dim draggedData As Object = draggedNode.Data
Dim draggedEmployee As Employee = Nothing
FindEmployee(draggedData.Id, Me.OrganizationModel.Employees, draggedEmployee)

If IsNothing(draggedEmployee) Then Exit Sub

'Get the dropped OrgChartNodeControl object.
Dim droppedEmployee As Employee = Nothing
Dim droppedNodeControl As OrgChartNodeControl = TryCast(e.DropTarget, OrgChartNodeControl)
If Not IsNothing(droppedNodeControl) Then
DropOnNode = True
'Get the dropped OrgChartNode object.
Dim droppedNode As OrgChartNode = droppedNodeControl.Node
'Get the underlying data.
Dim droppedData As Object = droppedNode.Data
FindEmployee(droppedData.Id, Me.OrganizationModel.Employees, droppedEmployee)
End If

If IsNothing(droppedEmployee) Then Exit Sub

'Prevent drop on self.
If draggedEmployee.Id = droppedEmployee.Id Then Exit Sub

'Check if the drop target already contains the dragged node.
If droppedEmployee.Subordinates.Contains(draggedEmployee) Then Exit Sub

'Remove the dragged Employee from old node
If Me.OrganizationModel.Employees.Contains(draggedEmployee) Then
Me.OrganizationModel.Employees.Remove(draggedEmployee)
Else
RemoveEmployee(draggedEmployee, Me.OrganizationModel.Employees)
End If

'Add the dragged employee to new node
If DropOnNode Then
If Not IsNothing(droppedEmployee) Then
droppedEmployee.Subordinates.Add(draggedEmployee)
End If
Else
Me.OrganizationModel.Employees.Add(draggedEmployee)
End If

End Sub

Private Sub FindEmployee(ByVal Id As String, ByRef Employees As ObservableCollection(Of Employee), ByRef FoundEmployee As Employee)

If IsNothing(FoundEmployee) Then
For Each emp As Employee In Employees
If IsNothing(FoundEmployee) Then
If emp.Id = Id Then
FoundEmployee = emp
Else
FindEmployee(Id, emp.Subordinates, FoundEmployee)
End If
End If
Next
End If

End Sub

Private Sub RemoveEmployee(ByVal Employee As Employee, ByRef Employees As ObservableCollection(Of Employee))

If Not IsNothing(Employee) Then
For Each emp As Employee In Employees
If emp.Subordinates.Count > 0 Then
If emp.Subordinates.Contains(Employee) Then
emp.Subordinates.Remove(Employee)
Else
RemoveEmployee(Employee, emp.Subordinates)
End If
End If
Next
End If

End Sub

  • 1760
    posted

    Hi,

    A drag template property is of type DataTemplate. So I think it is possible to create a datatemplate in code behind and to apply it on drag start as it is shown in our samples.

    Thanks,

    M.Yovchev