【问题标题】:How do I set focus to a control within the ItemTemplate when the ListBoxItem is selected?选择 ListBoxItem 时,如何将焦点设置到 ItemTemplate 中的控件?
【发布时间】:2011-06-08 07:46:34
【问题描述】:

我有一个使用 DataTemplate 呈现对象的 ListBox。 DataTemplate 包含一个文本框。当用户在 ListBox 中选择一个项目时,我想将焦点设置到所选项目的 TextBox。

我已经能够通过处理 ListBox.SelectionChanged 部分地实现这一点,但它仅在用户单击 ListBox 以选择项目时才有效 - 如果用户选择进入 ListBox 并使用箭头键选择项目,即使 TextBox.Focus() 被调用

当用户使用键盘选择项目时,如何将焦点设置到 TextBox?

这是 ListBox 的标记:

<ListBox Name="lb1" SelectionChanged="ListBox_SelectionChanged" ItemsSource="{Binding Items}" >
    <ListBox.ItemTemplate>
        <DataTemplate >
            <TextBox></TextBox>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这里是处理代码:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBoxItem lbi = (ListBoxItem)this.lb1.ItemContainerGenerator.ContainerFromItem(this.lb1.SelectedItem);
    Visual v = GetDescendantByType<TextBox>(lbi);
    TextBox tb = (TextBox)v;
    tb.Focus();
}

【问题讨论】:

    标签: wpf focus datatemplate listboxitem


    【解决方案1】:

    一种方法是将tb.Focus() 中的SelectionChanged 事件处理程序替换为:

    tb.Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(delegate()
            {
                tb.Focus();
            }));
    

    这是因为在调度程序上调用 BeginInvoke 会导致指定代码在调度程序可用时运行 - 即在 WPF 完成内部处理事件之后。

    问题是,当列表项获得焦点时,第一次按下向下箭头后,下一个列表项将被选中,其文本框将成为焦点,您将无法再次使用向下箭头移动选择。您可能也想编写一些代码来处理这种情况。

    【讨论】:

    • 不错 :) 希望您不介意我在答案中添加一句话来解释 为什么 它有效。我不得不说它感觉有点脏,但它完成了工作。
    • 哇。那条线是节省时间的!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    相关资源
    最近更新 更多