C# 关注已添加的项控件项,但不关注完全刷新
在我们的C# 关注已添加的项控件项,但不关注完全刷新,c#,wpf,focus,caliburn.micro,behavior,C#,Wpf,Focus,Caliburn.micro,Behavior,在我们的C#WPF应用程序(使用Caliburn.Micro)中,我们可以看到一些文本框、下拉列表等。我们还有一些ViewModels列表,其中包含一个按钮,用于向这些单独的ItemsControl列表添加其他项。对于此视图,我们创建了一个如下工作的行为: 当我们使用ItemsControl下面的按钮添加新项时,我们 添加项目并聚焦第一个可聚焦的元素(几乎在 所有案例(文本框)都包含此添加项目的 这正是我们想要的。现在的问题是,在刷新数据时,它还将焦点转移到视图的最后一项控件的第一项。数据刷
C#WPF
应用程序(使用Caliburn.Micro
)中,我们可以看到一些文本框、下拉列表等。我们还有一些ViewModels列表,其中包含一个按钮,用于向这些单独的ItemsControl列表添加其他项。对于此视图,我们创建了一个如下工作的行为:
- 当我们使用ItemsControl下面的按钮添加新项时,我们 添加项目并聚焦第一个可聚焦的元素(几乎在 所有案例(文本框)都包含此添加项目的
- 保持焦点行为,以便在刷新数据时不正确地移动焦点
- 删除FocusBehavior,这样它就不会在数据刷新时错误地移动焦点,但是当我们将一个新项添加到其中一个项控件时,它仍然会聚焦“添加”按钮,而不是新项的第一个文本框
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace NatWa.MidOffice.Behaviors
{
public class FocusSpecificBehavior : Behavior<ItemsControl>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += ItemsControlLoaded;
}
protected override void OnDetaching()
{
base.OnDetaching();
((INotifyCollectionChanged)AssociatedObject.Items).CollectionChanged -= CollectionChanged;
}
private void ItemsControlLoaded(object sender, RoutedEventArgs e)
{
AssociatedObject.Loaded -= ItemsControlLoaded;
((INotifyCollectionChanged)AssociatedObject.Items).CollectionChanged += CollectionChanged;
}
private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action != NotifyCollectionChangedAction.Add || AssociatedObject.Items.Count == 0) return;
var lastItem = (FrameworkElement)AssociatedObject.ItemContainerGenerator.ContainerFromIndex(AssociatedObject.Items.Count - 1);
if (lastItem == null) return;
if (lastItem.IsLoaded)
SetFocus(lastItem);
lastItem.Loaded += SetFocus;
}
private static void SetFocus(object sender, RoutedEventArgs e)
{
if (sender == null) return;
var lastItem = (FrameworkElement)sender;
lastItem.Loaded -= SetFocus;
SetFocus(lastItem);
}
private static void SetFocus(UIElement item)
{
item.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
}
}
}
使用System.Collections.Specialized;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
使用System.Windows.Interactive;
名称空间NatWa.MidOffice.Behaviors
{
公共类焦点特定行为:行为
{
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.Loaded+=ItemsControlLoaded;
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
((INotifyCollectionChanged)AssociatedObject.Items)。CollectionChanged-=CollectionChanged;
}
私有无效项控件已加载(对象发送方,路由目标)
{
AssociatedObject.Loaded-=ItemsControlLoaded;
((INotifyCollectionChanged)AssociatedObject.Items)。CollectionChanged+=CollectionChanged;
}
私有void CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
if(e.Action!=NotifyCollectionChangedAction.Add | | AssociatedObject.Items.Count==0)返回;
var lastItem=(FrameworkElement)AssociatedObject.ItemContainerGenerator.ContainerFromIndex(AssociatedObject.Items.Count-1);
if(lastItem==null)返回;
如果(lastItem.IsLoaded)
设置焦点(最后一项);
lastItem.Loaded+=SetFocus;
}
私有静态void SetFocus(对象发送方,路由目标)
{
if(sender==null)返回;
var lastItem=(FrameworkElement)发送方;
lastItem.Loaded-=SetFocus;
设置焦点(最后一项);
}
私有静态void SetFocus(UIElement项)
{
MoveFocus(新的遍历请求(FocusNavigationDirection.First));
}
}
}
因此,当ItemsControl列表中的某些内容发生更改时,我们将进入上面的CollectionChanged
方法。我在其中放置了一个断点以进行一些测试。当数据被重新加载时,它还会引发一个NotifyCollectionChangedAction.Add
。我还检查了从sender
检索到的ItemsControl/list的计数和从Args e
检索到的当前索引是否可以做些什么,但是在刷新数据或添加新项时,sender
和Args e
看起来完全相同
那么,是否有人知道如何修改此行为,使其集中于ItemsControl中添加的项,但同时不会在数据刷新/重置时触发?检查e.NewItems
的计数是否有效?我很惊讶刷新会引发集合更改事件,并带有NotifyCollectionChangedAction.Add
。。。是自定义刷新事件吗?@Rachel是的,它是一个自定义刷新,可重新加载所有数据。关于e.NewItems计数
,它始终是1,无论是在数据重新加载时,还是在项目通过NotifyCollectionChangedAction.Add增加1时,还是在我通过单击按钮添加单个项目时。