焦点添加了ItemsControl项目,但没有完全刷新

时间:2015-02-26 15:41:34

标签: c# wpf focus caliburn.micro behavior

在我们的C# WPF应用中(带有Caliburn.Micro),我们有一个带有一些TextBox,Dropdown等视图。我们还有一些ViewModel列表,其中包含一个按钮,可以将其他项添加到这些单独的ItemsControl列表中。对于此View,我们创建了一个行为,其行为如下:

  • 当我们使用ItemsControl下方的按钮添加新项目时,我们 添加项目并聚焦第一个可聚焦元素(差不多 这个添加项目的所有情况都是TextBox。

这是按预期工作的。我们现在遇到的问题是它还会将焦点转移到View的最后一个ItemsControl的第一项,即我们刷新数据的那一刻。数据刷新是必需的,所以现在我们有以下两个选项之一:

  • 保留FocusBehavior,以便在刷新数据时错误地移动焦点。
  • 删除FocusBehavior,因此它不会在数据刷新时错误地移动焦点,但是当我们向其中一个ItemsControls添加新项目时,它仍然会聚焦添加按钮而不是新项目的第一个TextBox。 / LI>

这两个选项都不是真的可以解决,所以我想修改行为,这样它只会在我们使用其中一个按钮添加项目时触发,而不是在数据刷新时触发。

以下是行为的代码:

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));
        }
    }
}

因此,当ItemsControl列表中的某些内容发生更改时,我们会进入上面的CollectionChanged方法。我在其中放置了一个断点进行一些测试。重新加载数据时,它也会不幸地引发NotifyCollectionChangedAction.Add。我还检查了我是否可以对从Count检索到的ItemsControl /列表的sender和从Args e检索到的当前索引执行某些操作,但{{1}在刷新数据或添加新项目时,sender看起来完全相同。

那么,有没有人知道如何修改这个行为,所以它集中了ItemsControl的添加项,但同时它不会触发数据刷新/重置?

0 个答案:

没有答案