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()
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
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)
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
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
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
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