如何通过带有 TextBox 作为 TreeViewItems 的 ListView 进行 TAB 操作?

问题描述 投票:0回答:4

所以我基本上有这个 ListView,我想按 Tab 并迭代我的 TreeViewItems(最好只有我的 TextBoxes)

<ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn  Header="number"  />
            <GridViewColumn Header="Selector">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding SelectorName}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

我看到的场景是第一次按下选项卡后,整个第一个 TreeViewItem 被选中,再次按下选项卡,第一个文本框被选中。最后,第三个选项卡从 TreeView 中移出到下一个控件,尽管还有更多的文本框我想在“标记”到下一个控件之前捕获它。 谢谢

编辑: 问题在这里得到了回答: 如何在 ListView 中通过 TextBox 进行 TAB 操作

wpf xaml listview textbox datatemplate
4个回答

2
投票

也许我遗漏了一些东西,但我找不到任何简单的方法来做到这一点,这里是你可以做什么的概述:

<ListView.InputBindings>
    <KeyBinding Key="Tab" Command="{Binding GoToNextItem}"
            CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListView}}" />
    <KeyBinding Modifiers="Shift" Key="Tab" Command="{Binding GoToPreviousItem}"
            CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListView}}" />
</ListView.InputBindings>
<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <EventSetter Event="Selected" Handler="ItemSelected" />
    </Style>
</ListView.ItemContainerStyle>
<ListView.View>
    <GridView>
        <GridViewColumn  Header="number"  />
        <GridViewColumn Header="Selector">
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Name="_tb" Text="{Binding SelectorName}"/>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
    </GridView>
</ListView.View>

我在这里做的事情:

  • 覆盖选项卡行为以触发命令来选择另一个项目
  • 将事件处理程序添加到选定的事件以聚焦文本框
  • 命名文本框,以便可以找到并聚焦它

代码:

private readonly ICommand _GoToNextItem = new Command((p) =>
    {
        var lv = p as ListView;
        if (lv.SelectedIndex == -1 || lv.SelectedIndex == lv.Items.Count - 1)
        {
            lv.SelectedIndex = 0;
        }
        else
        {
            lv.SelectedIndex++;
        }
    });
public ICommand GoToNextItem { get { return _GoToNextItem; } }

private readonly ICommand _GoToPreviousItem = new Command((p) =>
{
    var lv = p as ListView;
    if (lv.SelectedIndex <= 0)
    {
        lv.SelectedIndex = lv.Items.Count - 1;
    }
    else
    {
        lv.SelectedIndex--;
    }
});
public ICommand GoToPreviousItem { get { return _GoToPreviousItem; } }
private void ItemSelected(object sender, RoutedEventArgs e)
{
    var item = sender as ListBoxItem;
    (FindNamedChild(item, "_tb") as TextBox).Focus();
}

public static object FindNamedChild(DependencyObject container, string name)
{
    if (container is FrameworkElement)
    {
        if ((container as FrameworkElement).Name == name) return container;
    }
    var ccount = VisualTreeHelper.GetChildrenCount(container);
    for (int i = 0; i < ccount; i++)
    {
        var child = VisualTreeHelper.GetChild(container, i);
        var target = FindNamedChild(child, name);
        if (target != null)
        {
            return target;
        }
    }
    return null;
}

这是非常粗略的,使用其中任何部分的风险由您自行承担。 (我认为,在不将选择带入其中的情况下,对焦也可以采用不同的方式完成

Command
类只是
ICommand
的通用实现,它采用在接口的
Execute
方法中执行的lambda)


0
投票
在 GridViewColumn 和单元格模板上设置 IsTabStop="False"。现在应该只选择 选项卡更改时数据模板内的文本框。

试试这个:

<ListView DataContext="List" IsTabStop="False" > <ListView.View> <GridView> <GridViewColumn Header="Name" /> <GridViewColumn Header="Selector"> <GridViewColumn.CellTemplate> <DataTemplate > <TextBox Text="{Binding Name}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>
    

0
投票
我来到这里是因为我有一个包含文本框的 UserControls ListView,并且我希望能够在列表中进行选项卡导航。这里的解决方案对我来说不起作用,但是,所做的只是将 ListView 更改为 ItemsControl。 UI 现在完全按照我的预期工作,并且根本不需要对代码进行任何更改。

© www.soinside.com 2019 - 2024. All rights reserved.