none
treeview hierarchicaldatatemplate drag and drop RRS feed

  • Question

  • i have treeview in my WPF application 

    <TreeView HorizontalAlignment="Left"    ItemsSource="{Binding MyData}"  x:Name="trvFamilies"  Background="{x:Null}"  Margin="0,42,0,0" Width="243" Padding="0"   BorderThickness="0" >
    <TreeView.Resources>
                                                     
                                                    <HierarchicalDataTemplate DataType="{x:Type local:Family}"  ItemsSource="{Binding Children}">
                                                        <StackPanel Orientation="Horizontal">
                                                            <Image Source="{Binding myImg }" Margin="5,0,5,0" Height="18" Width="18" >  </Image>
                                                            <TextBlock Text="{Binding Path=myName}" Width="167" Padding="0,3,0,0"   TextTrimming="CharacterEllipsis" >  </TextBlock>
                                                            <Label Content="{Binding myAge}" Foreground="#FF515151" Width="39"  HorizontalContentAlignment="Right" Margin="0,0,12,0"> </Label>
    
                                                        </StackPanel>
                                                    </HierarchicalDataTemplate>
                                                    <DataTemplate DataType="{x:Type local:FamilyMember}"  >
                                                        <StackPanel Orientation="Horizontal">
                                                            <Image Source="{Binding Img}" Margin="21,0,5,0" Height="18" Width="18" />
                                                            <TextBlock  x:Name="surl" Text="{Binding Name}" Width="158" TextTrimming="CharacterEllipsis" Padding="0,3,0,0"     />
    
                                                            <Label Content="{Binding Age}" Foreground="#FF515151"  Width="30"   HorizontalContentAlignment="Right"  Margin="0,0,12,0"/>
    
                                                        </StackPanel>
                                                    </DataTemplate>
      </TreeView.Resources>
    </TreeView>

    and i populate the treeview in code behind

    public ObservableCollection<Family> MyData { get; set; }
      public HomePage()
            {
                InitializeComponent();
                
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(System.IO.Directory.GetCurrentDirectory() + "//FamilyBook.xml");
                 XmlNodeList nodeName = xmlDoc.GetElementsByTagName("Name");
                XmlNodeList nodeGender = xmlDoc.GetElementsByTagName("Gender");
                XmlNodeList nodeAge = xmlDoc.GetElementsByTagName("Age");
                XmlNodeList nodeImg = xmlDoc.GetElementsByTagName("Icon");
                XmlNodeList elemList = xmlDoc.GetElementsByTagName("item");
                MyData = new ObservableCollection<Family>();
                for (int i=0; i < elemList.Count; i++)
                {
                    MyData.Add(new Family()
                    {
    				    myName = nodeName[i].InnerText,
                        myGender = nodeGender[i].InnerText,
                        myAge= Convert.ToInt32(nodeAge[i].InnerText),
                       
                        myImg = System.IO.Directory.GetCurrentDirectory() + "/favicon/" + nodeImg[i].InnerText 
                         
                    });
                }   
              
    
            }
    public class Family : INotifyPropertyChanged
        {
            public Family()
            {
                this.Children = new ObservableCollection<FamilyMember>();
            }
            private int _myage;
    
            public int myAge
            {
                get { return _myage; }
                set
                {
                    if (_myage != value)
                    {
                        _myage = value;
                        OnPropertyChanged("Age");
                    }
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
    
    
            protected void OnPropertyChanged(string p_strPropertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(p_strPropertyName));
            }
            public string myName { get; set; }
            public string myGender { get; set; }
    		 public string myImg { get; set; }
           
            public ObservableCollection<FamilyMember> Children { get; set; }
        }
    	
    	public class FamilyMember
        {
            public string Name { get; set; }
    
            public string Age { get; set; }
            public string Img { get; set; }
    
           
    
        }

    I am using xml file like this

                                                                                  <?xml version="1.0" encoding="UTF-8"?>
    										<Collection>
    										<item Name="James">
    										<Name>James Hoffman</Name>
    										<Age>23</Age>
    										<Gender>Male</Gender> 
    										<Icon>james.png</Icon>
    										<item>
    										</Collection>

    i need help to make Drag and Drop between node and save automatically the structure in the xml file.

    i found many tutorials but any threads about my case ( hierarchicaldatatemplate with xml file)

    Thanks in advance

    Regards.



    Monday, April 7, 2014 2:15 PM

Answers

  • Hi,

    >>i need help to make Drag and Drop between node and save automatically the structure in the xml file.

    To implement drag and drop functionality, we need to handle the these events: PreviewMouseLeftButtonDown, MouseMove, PreviewDragEnter, PreviewDrop:

    <TreeView HorizontalAlignment="Left" AllowDrop="True" ItemsSource="{Binding MyData}"  x:Name="trvFamilies"  Background="{x:Null}"  Margin="0,42,0,0" Width="250" Padding="0"   BorderThickness="0" PreviewMouseLeftButtonDown="TV_PreviewMouseLeftButtonDown" MouseMove="TV_MouseMove" PreviewDragEnter="trvFamilies_PreviewDragEnter" PreviewDrop="trvFamilies_PreviewDrop" >
    ......

    int flag = 0;
    Point startPoint;
    private void TV_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
                // Store the mouse position
                startPoint = e.GetPosition(null);
                flag = 1;
    }
    
    
    private void TV_MouseMove(object sender, MouseEventArgs e)
    {
                if(flag==1)
                { 
                // Get the current mouse position
                Point mousePos = e.GetPosition(null);
                Vector diff = startPoint - mousePos;
    
                if (e.LeftButton == MouseButtonState.Pressed &&
                    Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
                    Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
                {
                    // Get the dragged ListViewItem
                    TreeView treeView = sender as TreeView;
                    TreeViewItem treeViewItem =
                        FindAnchestor<TreeViewItem>((DependencyObject)e.OriginalSource);
    
                    // Find the data behind the ListViewItem
                    Family contact = (Family)treeView.ItemContainerGenerator.ItemFromContainer(treeViewItem);
    
                    // Initialize the drag & drop operation
                    DataObject dragData = new DataObject("myFormat", contact);
                    DragDrop.DoDragDrop(treeViewItem, dragData, DragDropEffects.Move);
                }
                }
    }
    
    
    // Helper to search up the VisualTree
    private static T FindAnchestor<T>(DependencyObject current)
                where T : DependencyObject
    {
                do
                {
                    if (current is T)
                    {
                        return (T)current;
                    }
                    current = VisualTreeHelper.GetParent(current);
                }
                while (current != null);
                return null;
    }
    
    private void FindDropTarget( TreeView tv, out TreeViewItem pItemNode, DragEventArgs pDragEventArgs)
    {
                pItemNode = null;
    
                DependencyObject k = VisualTreeHelper.HitTest(tv, pDragEventArgs.GetPosition(tv)).VisualHit;
    
                while (k != null)
                {
                    if (k is TreeViewItem)
                    {
                        TreeViewItem treeNode = k as TreeViewItem;
                        if (treeNode.DataContext is Family)
                        {
                            pItemNode = treeNode;
                        }
                    }
                    else if (k == tv)
                    {
                        Console.WriteLine("Found treeview instance");
                        return;
                    }
    
                    k = VisualTreeHelper.GetParent(k);
                }
    }
    
    private void trvFamilies_PreviewDragEnter(object sender, DragEventArgs e)
    {
                if (!e.Data.GetDataPresent("myFormat") || sender == e.Source)
                {
                    e.Effects = DragDropEffects.None;
                }
    }
    
    private void trvFamilies_PreviewDrop(object sender, DragEventArgs e)
    {
                if (e.Data.GetDataPresent("myFormat"))
                {
                    TreeViewItem itemNode;
                    FindDropTarget((TreeView)sender, out itemNode, e);
                    Family dropItem = (itemNode != null && itemNode.IsVisible ? itemNode.DataContext as Family : null);
                    Family dragItem = e.Data.GetData("myFormat") as Family;
                    TreeView treeView = sender as TreeView;
                    Console.WriteLine("Index: "+(MyData.IndexOf(dropItem) + 1).ToString());
                    MyData.Remove(dragItem);
                    MyData.Insert(MyData.IndexOf(dropItem)+1,dragItem);
                    flag = 0;
                }
    }

    Download sample: http://1drv.ms/1g0uCu4


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, April 8, 2014 7:42 AM
    Moderator