【问题标题】:WPF ItemsControl - how to know when the itemscontrol finished loading, so that I can focus the first one?WPF ItemsControl - 如何知道 itemscontrol 何时完成加载,以便我可以关注第一个?
【发布时间】:2014-07-30 12:04:55
【问题描述】:

在我的视图中有一个 ItemsControl,它绑定到来自 ViewModel 的 ObservableCollection。集合被填充,然后引发从 VM 到视图的事件(想想搜索结果和 SearchFinished 事件)。 如何将键盘焦点移动到 ItemsControl 中的第一项? 我正在使用 MVVM 模式

【问题讨论】:

  • 也许你应该尝试 ItemsControl 的 LayoutUpdated 事件,在它的处理程序中找到它的第一个孩子并使用 Keyboard.Focus(child)
  • 如何在viewmodel中创建LayoutUpdated事件?
  • 您在视图后面的代码中创建它,它可以并且不违反 MVVM 模式,因为它的视图特定行为是您想要的
  • GeneratorStatus == ContainersGenerated 时,您可以使用ItemsControl.ItemContainerGenerator.Status 触发焦点事件
  • 你能给我一个 ItemsControl.ItemContainerGenerator.Status 的示例代码吗?

标签: wpf mvvm wpf-controls


【解决方案1】:

我在使用行为之前已经这样做了:

public sealed class FocusBehavior : Behavior<FrameworkElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Loaded += OnLoaded;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        AssociatedObject.Loaded -= OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        AssociatedObject.Focus();
    }
}

然后在 XAML 中使用如下:

<TextBox x:Name="UsernameTextBox"
         Text="{Binding Path=Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
         KeyboardNavigation.TabIndex="0">
    <i:Interaction.Behaviors>
        <b:FocusBehavior />
    </i:Interaction.Behaviors>
</TextBox>

您需要对 System.Windows.Interactivity 程序集的引用才能拉入 Interaction 命名空间。

【讨论】:

    【解决方案2】:

    我找到了解决方案..

    private void VerifiValue_Loaded(object sender, RoutedEventArgs e)
        {
            if (verificationIC.Items.Count > 0)
            {
                UIElement uiElement = (UIElement)verificationIC.ItemContainerGenerator.ContainerFromIndex(0);
    
                TextBox t = GetChild<TextBox>(uiElement);
                t.Focus();
                t.SelectAll();
            }
        }
    
        public T GetChild<T>(DependencyObject obj) where T : DependencyObject
        {
            DependencyObject child = null;
            for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child.GetType() == typeof(T))
                {
                    break;
                }
                else if (child != null)
                {
                    child = GetChild<T>(child);
                    if (child != null && child.GetType() == typeof(T))
                    {
                        break;
                    }
                }
            }
            return child as T;
        }
    

    【讨论】:

      猜你喜欢
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多