0

我有一个绑定到可观察集合的树视图。集合中的每个项目本身都有一个带有项目的可观察集合。

public class Item
{
  public ObservableCollection<Item> Items { get; set; }
  public Item Parent { get; set; }
}

public Item Root { get; set; }

<TreeView ItemsSource={Binding Root.Items}>
   <TreeView.ItemTemplate>
       <HierarchicalDataTemplate ItemsSource="{Binding Items}">
           <TextBlock Text="{Binding}" />
       </HierarchicalDataTemplate>
   </TreeView.ItemTemplate>
</TreeView>

我想将树中的一个节点从一个分支移动到另一个分支,但是这样做会使控件失去焦点和选择。

UnindentItemCommand = new DelegateCommand<Item>(
  item => 
  {
     var parent = item.Parent;
     parent.Items.Remove(item);
     parent.parent.Items.Add(item);         
  }
);

我曾尝试使用BindableSelectedItemBehaviorfrom another question,但没有帮助。

有人对此有解决方案吗?

4

2 回答 2

1

TreeView.SelectedItem从您的视图模型或后面的代码绑定到属性怎么样?:

<TreeView ItemsSource="{Binding Root.Items}" TreeView.SelectedItem="{Binding Item}">
   <TreeView.ItemTemplate>
       <HierarchicalDataTemplate ItemsSource="{Binding Items}">
           <TextBlock Text="{Binding}" />
       </HierarchicalDataTemplate>
   </TreeView.ItemTemplate>
</TreeView>

然后在您的节点移动代码中,您可以复制所选项目并在移动数据时重新设置它:

UnindentItemCommand = new DelegateCommand<Item>(
    item => 
    {
        Item selectedItem = Item;
        var parent = item.Parent;
        parent.Items.Remove(item);
        parent.parent.Items.Add(item);
        Item = selectedItem;
    }
);
于 2013-10-28T12:05:31.973 回答
0

我遇到了完全相同的问题。在我看来,这确实是 WPF 中的一个错误。移动可观察集合中的节点后,树会正确更新并选择正确的节点,但键盘焦点会丢失。对我有用的是通过获取第一个 treeviewitem 元素并明确设置焦点来稍微“摇动”树。然后我只需转到我移动的元素并将 IsSelected 属性设置为 false ,然后设置为 true ,这会将焦点带回它。不是最优雅的解决方案,但与我尝试过的所有其他解决方案相比,它非常简单,并且对最终用户来说看起来都是无缝的。

UnindentItemCommand = new DelegateCommand<Item>(
item => 
{
    Item selectedItem = Item;
    var parent = item.Parent;
    parent.Items.Remove(item);
    parent.parent.Items.Add(item);
    Item = selectedItem;

    TreeViewItem tvi = (TreeViewItem) 
(TreeName.ItemContainerGenerator.ContainerFromItem(TreeName.Items[0]));
    tvi.Focus();
    Keyboard.Focus(tvi);
    Item.IsSelected= false;    
    Item.IsSelected = true;    
}
);


<Style TargetType="{x:Type TreeViewItem}">
   <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
于 2019-12-19T16:31:25.610 回答