【问题标题】:Fail on focusing First child of an ItemsControls in WPF未能聚焦 WPF 中 ItemsControls 的第一个子项
【发布时间】:2017-01-04 04:44:41
【问题描述】:

我有一个 ItemsControl,它会在 ItemSource 为 null 时自动隐藏,并且在显示它自己之后应该关注第一个孩子。 通过简单地将以下处理程序添加到“IsVisibleChanged”事件,我实现了正确的触发:

if ((bool)e.NewValue)
{
    ItemsControl control = sender as ItemsControl;
    if (control != null)
    {
        control.UpdateLayout();
        Task task = Task.Run(delegate ()
            {
                while (control.Items.Count == 0 || 
                       control.ItemContainerGenerator.Status == GeneratorStatus.NotStarted ||
                       control.ItemContainerGenerator.Status == GeneratorStatus.GeneratingContainers) ;
            });

        if (await Task.WhenAny(task, Task.Delay(1000)) == task)
        {
            ContentPresenter first = control.ItemContainerGenerator.ContainerFromIndex(0) as ContentPresenter;
            if (first != null) (first.ContentTemplate.FindName("textBox", first) as System.Windows.UIElement).Focus();
        }
    }
}

处理程序在第一次显示 ItemsControls 时始终运行良好,但最后一行在第二次调用时抛出 InvalidOperationException。

处理程序的工作原理是等待 ItemContainerGenerator 完成其工作(或超时一秒),然后它获取 ItemsControl 的第一个容器并从容器中聚焦名为“textBox”的元素。

如果有人能告诉我哪里出了问题,我会很高兴,因为唯一需要执行的是if (first != null) (first.ContentTemplate.FindName("textBox", first) as System.Windows.UIElement).Focus(); 行。

异常消息:
此操作仅对应用了此模板的元素有效。

堆栈跟踪:
在 System.Windows.FrameworkTemplate.FindName(字符串名称,FrameworkElement templatedParent)
在 ***.d__1.MoveNext() ...

【问题讨论】:

  • 堆栈跟踪和引发异常的消息是什么?

标签: c# wpf


【解决方案1】:

我找到了一种自己工作的方法,问题在于容器没有完全初始化,所以我替换了最后一行来检查“IsLoaded”属性并执行一些额外的工作,并纠正了等待任务。

if ((bool)e.NewValue)
{
    ItemsControl control = sender as ItemsControl;
    if (control != null)
    {
        control.UpdateLayout();
        Task task = Task.Run(delegate ()
                    {
                        while (control.ItemContainerGenerator.Status == GeneratorStatus.NotStarted ||
                               control.ItemContainerGenerator.Status == GeneratorStatus.GeneratingContainers) ;
                    });

        if (await Task.WhenAny(task, Task.Delay(1000)) == task)
        {
            ContentPresenter first = control.ItemContainerGenerator.ContainerFromIndex(0) as ContentPresenter;
            if (first != null)
            {
                if (first.IsLoaded)
                {
                    (first.ContentTemplate.FindName("textBox", first) as System.Windows.UIElement).Focus();
                }
                else
                {
                    RoutedEventHandler onload = null;
                    onload = delegate
                    {
                        first.Loaded -= onload;
                        (first.ContentTemplate.FindName("textBox", first) as System.Windows.UIElement).Focus();
                    };
                    first.Loaded += onload;
                }
            }

        }
    }
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2011-06-05
    相关资源
    最近更新 更多