Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关注已添加的项控件项,但不关注完全刷新_C#_Wpf_Focus_Caliburn.micro_Behavior - Fatal编程技术网

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时,还是在我通过单击按钮添加单个项目时。