tags:

views:

415

answers:

0

I have a WPF treeview that is bound to an object tree. When I remove an item from the tree, the TreeView SelectedItem jumps to the parent node of the item that was deleted. I am trying to fix this problem and have tried a bunch of different things, including inheriting from the TreeView and TreeviewItem and overriding the OnItemsChanged event. Everything I try results in the same thing. Basically, if I put some kind of pause in the remove method, the code works as expected. But without the pause it does not work. It's very strange. Can someone please point me in the right direction. Here is my current implementation, I've tried to strip the code down as much as possible.

The main window XAML :

<Window x:Class="WpfApplication2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <TreeView Name="treeView1" ItemsSource="{Binding}" KeyDown="treeView1_KeyDown">
            <TreeView.ItemContainerStyle>
                <Style TargetType="TreeViewItem">
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                    <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                </Style>
            </TreeView.ItemContainerStyle>

            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>

Main window Code behind:

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApplication2
{
    public partial class Window1 : Window
    {
        private ObservableCollection<SomeObject> Children;

        public Window1()
        {
            InitializeComponent();

            Children = FillChildren();
            treeView1.DataContext = Children;
        }

        private ObservableCollection<SomeObject> FillChildren()
        {
            ObservableCollection<SomeObject> returnValue = new ObservableCollection<SomeObject>();

            SomeObject o = new SomeObject();
            o.Name = "Root node";

            SomeObject subOb1 = new SomeObject();
            subOb1.Name = "SubObject 1";
            subOb1.Parent = o;
            SomeObject subOb2 = new SomeObject();
            subOb2.Name = "SubObject 2";
            subOb2.Parent = o;
            SomeObject subOb3 = new SomeObject();
            subOb3.Name = "SubObject 3";
            subOb3.Parent = o;

            o.Children.Add(subOb1);
            o.Children.Add(subOb2);
            o.Children.Add(subOb3);

            returnValue.Add(o);
            return returnValue;
        }

        private void treeView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                TreeView tv = sender as TreeView;
                if (tv != null)
                {
                    SomeObject child = tv.SelectedItem as SomeObject;
                    if (child != null)
                    {
                        SomeObject parent = child.Parent;
                        parent.Children.Remove(child);

                        if (parent.Children.Count > 0)
                        {
                            parent.Children[0].IsSelected = true;
                        }
                    }
                }
            }
        }
    }
}

SomeObject code :

using System.Collections.ObjectModel;
using System.ComponentModel;

namespace WpfApplication2
{
    public class SomeObject : INotifyPropertyChanged
    {
        private SomeObject parent;
        private ObservableCollection<SomeObject> children;
        private bool isSelected;
        private bool isExpanded;
        private string name;

        public SomeObject Parent
        {
            get { return parent; }
            set { parent = value; }
        }
        public ObservableCollection<SomeObject> Children
        {
            get { return children; }
        }
        public bool IsSelected
        {
            get { return isSelected; }
            set
            {
                if (isSelected != value)
                {
                    isSelected = value;
                    NotifyPropertyChanged("IsSelected");
                }
            }
        }
        public bool IsExpanded
        {
            get { return isExpanded; }
            set
            {
                if (isExpanded != value)
                {
                    isExpanded = value;
                    NotifyPropertyChanged("IsExpanded");
                }
            }
        }
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                NotifyPropertyChanged("Name");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string controlName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(controlName));
            }
        }

        public SomeObject()
        {
            children = new ObservableCollection<SomeObject>();
        }
    }
}

Any help is greatly appreciated!!