按下删除键时 DataGrid 失去焦点
我正在做 MVVM,其中 DataGrid 绑定到 ObservableCollection,并使用连接到 DataGrid.InputBindings 的 DeleteItemCommand,如下所示:
<DataGrid.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteItemCommand}" />
</DataGrid.InputBindings>
当用户按下删除键但网格失去焦点时,项目和行将被删除。您必须单击或按 Tab 键切换到网格,以便它重新获得焦点,然后再单击“删除”以删除另一行(非常烦人)。我尝试设置 DataGrid.CanUserDeleteRows="False" 但没有任何区别。
我用 ListView 替换了 DataGrid,并且 ListView 保留了焦点。
这是 DataGrid 的错误还是我做错了什么?和平与爱,和平与爱!
I'm doing MVVM where a DataGrid is bound to an ObservableCollection with a DeleteItemCommand hooked up to the DataGrid.InputBindings as follows:
<DataGrid.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteItemCommand}" />
</DataGrid.InputBindings>
The item and row are removed when the user hits the delete key but the grid looses focus. You have to click or tab to the grid so it regains focus before hitting Delete to remove another row (pretty freaking annoying). I tried setting the DataGrid.CanUserDeleteRows="False" but it doesn't make any difference.
I replaced the DataGrid with a ListView and the ListView retains focus.
Is this a bug with the DataGrid or am I doing something wrong? Peace and love, peace and love!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我通过使用 WPF DataGrid 的内置功能解决了这个问题。如果底层集合是可编辑的,则默认情况下网格会处理删除项目(如果该集合专用于此目的,则没有问题,否则可以添加中间集合...)。我避免了任何键绑定,只是像这样设置网格:
ItemsSource 集合的类型为 BidningCollection<>。
在我的 ViewModel (我的 DataContext)中,我添加了 CollectionChanged 事件的处理程序:
InvoiceItems.CollectionChanged += InvoiceItemsCollectionChanged;
并像这样实现它:
那是因为您可能至少有两种方法从底层集合中删除项目(带有 Del 键的键盘,一些按钮),也许删除项目时需要注意的一些其他事项。
I solved this by using the built in functionality of WPF DataGrid. The grid handles removing items by default if the underlying collection is editable (if the collection is dedicated to this purpose that's no problem, otherwise an intermediate collection can be added...). I avoided any key bindings and just set up the grid like this:
<DataGrid ItemsSource="{Binding InvoiceItems}" IsReadOnly="False" CanUserDeleteRows="True" CanUserAddRows="False">
The ItemsSource collection is of type BidningCollection<>
In my ViewModel (my DataContext) I add a handler for CollectionChanged event:
InvoiceItems.CollectionChanged += InvoiceItemsCollectionChanged;
And implement it like this:
That's because you will probably be having at least two ways of removing an item from you underlying collection (keyboard with Del key, some button) and maybe some other things to take care of when an item is deleted.
我前段时间碰到过这一点。不知何故,这个事件从未被引发。
尝试
这种方法。
长话短说,事件
PreviewKeyDown
将带您到达您想要的位置。并以 MVVM 友好的方式:
I bumped on that some time ago. Somehow this event is never raised.
Try
this approach.
Long story short, event
PreviewKeyDown
will get you where you want.And in MVVM-friendly manner:
您检查过这个答案吗?
如何将删除操作(在 WPF Datagrid 中)绑定到视图模型中的命令或属性
您可能需要:
确保键实际上绑定到数据上下文中的指定命令,如下所示:
以前我在第 #2 项处失败并写入 Command="{Binding DeleteEntry}",而实际上我应该绑定通过RelativeSource 到DataContext.DeleteEntry。
Did you check this answer yet?
How to bind delete action (in WPF Datagrid) to a command or property in view model
You probably need to:
make sure the key is actually bound to the specified command in your datacontext, like this:
Previously I fail at item #2 and wrote Command="{Binding DeleteEntry}", while in fact I should bind to DataContext.DeleteEntry by RelativeSource.
我必须以不同于jl.的答案的方式解决问题,因为它无法进行任何处理< em>之前(例如检查访问权限)删除就像
命令
一样发生。虽然可能不那么强大,但它确实符合您的要求。保持原始代码不变,只需挂钩以下SelectionChanged
,或者更好地使用附加属性。因为删除一个项目首先会产生索引为 -1 的 SelectionChanged ,所以很容易可靠地猜测何时发生删除并设置一个标志。在第一次调用 -1 后,另一个具有最近邻居索引的调用发生,此时如果设置了标志,则可以安全地聚焦当前单元格:
其中
IsRemovalEvent
检查选择事件是否由项目删除:和
FocusCurrentCell
/GetChildren
是您可能已经有:I had to solve the issue in a different way than the jl.'s answer, because it could not do any processing before (e.g. checking access) deletion happen as a
Command
could. While perhaps not as robust, it does exactly what you asked about. Keeping your original code unchanged, just hook the followingSelectionChanged
, or even better use attached property.Because deleting an item first produces SelectionChanged with index -1 it is easy enough to reliably guess when deletion happen and set a flag. After the first invocation with -1 another one with nearest neighbor index happens, at this point if the flag was set, it is safe to focus the current cell:
where
IsRemovalEvent
checks if the selection event was produced by item removal:and the
FocusCurrentCell
/GetChildren
are helper methods you probably already have: