Click here to Skip to main content
15,881,812 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
I have run into a problem. In wpf I have a treeview populated by databinding. The following code is a subset of the complete code.

XAML:
XML
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:TreeViewItemViewModel}" ItemsSource="{Binding Path=Children}" >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Data}"/>
                <Button Content="Inside" Click="button2_Click" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <TreeView Height="287" HorizontalAlignment="Left" Margin="12,12,0,0" Name="treeView1" VerticalAlignment="Top" Width="186" />
        <Button Content="Outside" Height="23" HorizontalAlignment="Left" Margin="204,41,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
    </Grid>
</Window>



C#
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        ObservableCollection<TreeViewItemViewModel> nodes;
        protected override void OnActivated(EventArgs e)
        {
            nodes = new ObservableCollection<TreeViewItemViewModel>();
            nodes.Add(new TreeViewItemViewModel("1"));
            nodes.Add(new TreeViewItemViewModel("2"));
            nodes.Add(new TreeViewItemViewModel("3"));
            TreeViewItemViewModel viewModel = new TreeViewItemViewModel("4");
            viewModel.Parent = nodes[0];
            nodes[0].Children.Add(viewModel);
            treeView1.ItemsSource = nodes;
            base.OnActivated(e);
        }
        
        private void button2_Click(object sender, RoutedEventArgs e)
        {
            TreeViewItemViewModel viewModel = nodes[0].Children[0];
            nodes[0].Children.Remove(viewModel);
            viewModel.Parent = nodes[1];
            nodes[1].IsExpanded = true;
            nodes[1].Children.Add(viewModel);
            viewModel.IsExpanded = true;
            viewModel.IsSelected = true;
        }
    }
    public class TreeViewItemViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<TreeViewItemViewModel> Children { get; private set; }
        private bool _isExpanded;
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (_isExpanded != value)
                {
                    _isExpanded = value;
                    if (Parent != null)
                    {
                        Parent.IsExpanded = true;
                    }
                    OnPropertyChanged("IsExpanded");
                }
            }
        }
        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
            }
        }
        public TreeViewItemViewModel Parent { get; set; }
        public TreeViewItemViewModel(string data)
        {
            Data = data;
            Children = new ObservableCollection<TreeViewItemViewModel>();
        }
        public string Data { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}




I am trying to move treeviewitem "4" under treeviewitem "2". After the moving I want to select the moved treeviewitem ("4"). If I push the button "outside" or the button "inside" for treeviewitem "3" it works perfect. However, if I push the button "inside" for treeviewitem "4" (the one we are moving), it moves the item, but it does not select it. What am I doing wrong?
Posted

1 solution

Your button click event has nothing to do with "different" items as it is hard coded to take the first child out of the first node remove it and add it to the second node. So I am thinking it is more order of which you press. (once the effect happend it will happen again on Node 0 first child to Node 1, but it may not be present)

Also I would recomend not using the click event but instead use an ICommand interface [^] and set the button command path to it using binding[^].
The command should exist at the "TreeViewItemViewModel" for the button "inside" as that is the object type for the collection.

As for the "outside" event you have no knowledge of which item is to move so you are forced to do the hard coding that you have. Not sure what your intentions are exactly but you may want to think about if that makes sence or not.
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900