2010-06-02 2 views
0

로 이동합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?삭제 내가 여기서 논의 된 솔루션을 시도 부모

MainWindow.xaml

<Window x:Class="TreeViewDelete.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Tree View Delete sample" Height="350" Width="525"> 

<Window.Resources> 
    <Style TargetType="TreeViewItem"> 
     <Setter Property="IsSelected" Value="{Binding Selected, Mode=TwoWay}"/> 
     <EventSetter Event="KeyDown" Handler="OnTreeKeyDown"/> 
    </Style> 
    <HierarchicalDataTemplate x:Key="recursiveTemplate" ItemsSource="{Binding Children}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Name}"/> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
</Window.Resources> 
<Grid> 
    <TreeView Name="m_tree" ItemsSource="{Binding Children}" ItemTemplate="{StaticResource recursiveTemplate}"/> 
</Grid> 
</Window> 

MainWindow.xaml.cs를

public partial class MainWindow : Window 
{ 
    private Container m_root, m_child; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     m_root = new Container("Root"); 

     m_child = new Container("main"); 

     m_child.Add(new Container("k1")); 
     m_child.Add(new Container("k2")); 
     m_child.Add(new Container("k3")); 
     m_child.Add(new Container("k4")); 
     m_child.Add(new Container("k5")); 

     m_root.Add(m_child); 

     m_tree.DataContext = m_root; 
    } 

    private IEnumerable<T> GetVisualAncestorsOfType<T>(DependencyObject obj) where T : DependencyObject 
    { 
     for (; obj != null; obj = VisualTreeHelper.GetParent(obj)) 
      if (obj is T) 
       yield return (T)obj; 
    } 

    private void OnTreeKeyDown(object sender, KeyEventArgs e) 
    { 
     switch (e.Key) 
     { 
      case Key.Delete: 
       { 
        TreeViewItem item = sender as TreeViewItem; 

        if (item != null) 
        { 
         Container container = item.Header as Container; 

         if (container != null) 
         { 
          Container parent = container.Parent; 

          // Find the currently focused element in the TreeView's focus scope 
          DependencyObject focused = 
           FocusManager.GetFocusedElement(
           FocusManager.GetFocusScope(m_tree)) as DependencyObject; 

          // Scan up the VisualTree to find the TreeViewItem for the parent 
          var parentContainer = (
           from element in GetVisualAncestorsOfType<FrameworkElement>(focused) 
           where (element is TreeViewItem && element.DataContext == parent) 
            || element is TreeView 
           select element 
          ).FirstOrDefault(); 

          parent.Remove(container); 

          if (parentContainer != null) 
          { 
           parent.Children[0].Selected = true; 
           parentContainer.Focus(); 
          } 
         } 
        } 

        e.Handled = true; 
       } 
       break; 
     } 
    } 
} 

마지막 Container.cs

public class Container : INotifyPropertyChanged 
{ 
    private bool m_selected; 
    private string m_name; 
    private ObservableCollection<Container> m_children; 
    private Container m_parent; 

    public Container(string name) 
    { 
     m_name = name; 
     m_children = new ObservableCollection<Container>(); 
     m_parent = null; 
     m_selected = false; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public string Name 
    { 
     get 
     { 
      return m_name; 
     } 

     set 
     { 
      m_name = value; 

      OnPropertyChanged("Name"); 
     } 
    } 

    public Container Parent 
    { 
     get 
     { 
      return m_parent; 
     } 

     set 
     { 
      m_parent = value; 
     } 
    } 

    public bool Selected 
    { 
     get 
     { 
      return m_selected; 
     } 

     set 
     { 
      m_selected = value; 

      OnPropertyChanged("Selected"); 
     } 
    } 

    public ObservableCollection<Container> Children 
    { 
     get 
     { 
      return m_children; 
     } 
    } 

    private void OnPropertyChanged(string name) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    public void Add(Container child) 
    { 
     m_children.Add(child); 

     child.Parent = this; 
    } 

    public void Remove(Container child) 
    { 
     m_children.Remove(child); 

     child.Parent = null; 
    } 
} 

답변

0

나는 여기서 제공되는 솔루션을 시도 : "TreeView selected item when removing nodes"를 간단한 응용 프로그램에서 아름답게 작동합니다. 응용 프로그램에서 말할 필요도없이 ...

내 기사를 볼 때 TreeViewItem이 필요합니다. 내 항목의 컨테이너 인 것 같습니다. 그래서 시도 :

m_tree.ItemContainerGenerator.ContainerFromItem 

항상 null을 반환합니다. 그 다음 나는 다음과 같이 읽었다 : TreeView.ItemContainerGenerator.ContainerFromItem returns null, 어느 시점에서 나의 두뇌는 거의 퓨즈를 날려 버렸다!

내가 선택하고 싶은 TreeViewItem에있는 것처럼 보입니다. 원하는 위치에 도달 할 때까지 계층 구조의 맨 위에서 시작하여 트리 아래로 작업해야합니다. 그래서, 내 컨테이너 데이터가 Parent 속성을 가지고, 그래서 객체의 스택 구축 :

Stack<Containerl> stack = new Stack<Container>(); 

Container toBeSelected = ... my object to be selected after deletion ... 

while (toBeSelected != null) 
{ 
    stack.Push(toBeSelected); 

    toBeSelected = toBeSelected.Parent; 
} 

다음 내 계층 구조에서 모든 항목을 삭제를 한 후 다음을 수행하십시오

TreeViewItem item = m_tree.ItemContainerGenerator.ContainerFromItem(stack.Pop()) as TreeViewItem; 

while(item != null && (stack.Count > 0)) 
{ 
    item = item.ItemContainerGenerator.ContainerFromItem(stack.Pop()) as TreeViewItem; 
} 

// Force this item to be selected, and set focus 
item.IsSelected = true; 
item.Focus(); 

그것은 작동한다! !! !!

0

나는이에게 자신을 확인하지 않았다하지만 난 당신이 할 수있는 생각 ObservableCollections의 CollectionChanged 이벤트를 사용하여이 작업을 수행하십시오. 여기에 자식 컬렉션에 이벤트를 첨부하여 그 중 하나가 삭제 될 때 컬렉션의 첫 번째 자식과 같은 Selected 속성을 true로 설정할 수 있습니다. 다음과 같은 코드 :

이벤트를 첨부 :

Children.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Children_CollectionChanged); 

이벤트 구현 :

void Children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
{ 
    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove) 
    { 
     Children.First().Selected = true; 
    } 
} 
+0

내가 이미하는 일이 아닌가요? parent.Children [0] .Selected = true; – imekon

관련 문제