【问题标题】:ListView Tab Navigation Across Columns where ListViewItems are GridsListView 选项卡导航跨 ListViewItems 是网格的列
【发布时间】:2012-08-24 13:06:55
【问题描述】:

我有一个水平显示项目的 ListView。每个项目都是一个 1 列网格。外观是一个网格,其中列数是动态的。除了标签导航之外,所有这些都有效并且看起来像我想要的那样。我在 ListView 上设置了 KeyboardNavigation.TabNavigation="Continue" 并在 ItemContainerStyle 上将 KeyboardNavigation.IsTabStop 设置为 false,这允许我通过项目中的每一行,然后进入下一个项目,等等。但是,我想从第一项的第一行到第二项的第一行,依此类推,然后到下一行。

例如。

Item1Row1 -> Item2Row1 -> Item3Row1 -> ...

Item1Row2 -> Item2Row2 -> Item3Row2 -> ...

我为每个单元格中的控件设置了选项卡索引(我已经测试过是正确的),但我无法弄清楚在 ListView/ListViewItems 中启用 TabIndexes 需要哪些设置。任何帮助将不胜感激。这是 xaml...

<ListView VerticalAlignment="Top" Background="Transparent" BorderThickness="0" KeyboardNavigation.TabNavigation="Continue" ItemsSource="{Binding RawProductDataItemViewModels}">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Focusable" Value="False"/>
            <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid VerticalAlignment="Top" Margin="2.5,0,2.5,0">
                <Grid.RowDefinitions>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                    <RowDefinition SharedSizeGroup="ButtonAndGridGroup"/>
                </Grid.RowDefinitions>

                <TextBlock Margin="5,4,0,0" Grid.Row="0">
                        <TextBlock.Text>
                            <MultiBinding StringFormat="Lane #{0}">
                                <Binding Path="Lane"/>
                            </MultiBinding>
                        </TextBlock.Text>
                </TextBlock>
                <TextBox Grid.Row="1" Margin="0,4,0,0" Width="75" Text="{Binding RollNumber, StringFormat='{}{0:#####-#}', TargetNullValue=''}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=1}"/>
                <TextBox Grid.Row="2" Margin="0,4,0,0" Width="75" Text="{Binding PCode}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=2}"/>
                <TextBox Grid.Row="3" Margin="0,4,0,0" Width="75" Text="{Binding RollWidth}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=3}"/>
                <TextBox Grid.Row="4" Margin="0,4,0,0" Width="75" Text="{Binding RollWeight}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=4}"/>
                <TextBox Grid.Row="5" Margin="0,4,0,0" Width="75" Text="{Binding GrossWeight}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=5}"/>
                <TextBox Grid.Row="6" Margin="0,4,0,0" Width="75" Text="{Binding BurnWeight}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=6}"/>
                <TextBox Grid.Row="7" Margin="0,4,0,0" Width="75" Text="{Binding SqFtWeight}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=7}"/>
                <TextBox Grid.Row="8" Margin="0,4,0,0" Width="75" Text="{Binding Cure}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=8}"/>
                <TextBox Grid.Row="9" Margin="0,4,0,0" Width="75" Text="{Binding Rigidity}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=9}"/>
                <TextBox Grid.Row="10" Margin="0,4,0,0" Width="75" Text="{Binding Telescope}"
                            TabIndex="{Binding Lane, Converter={StaticResource IntegersTo2DIndex}, ConverterParameter=10}"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

【问题讨论】:

    标签: wpf xaml listview tabindex keyboard-navigation


    【解决方案1】:

    我决定在后面的代码中处理这个问题。我删除了 xaml 中文本框上的选项卡索引。该解决方案并不漂亮,但在我看来,这比删除列表框并对所有通道进行编码以便我可以使用选项卡索引更好。

    在 ListView 上预览 Key Down 处理程序:

    private void LanesListView_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        UIElement uie = e.OriginalSource as UIElement;
    
        // 'Ctrl + Tab' or 'Shift + Enter' (Reverse Tab)
        if ((e.Key == Key.Tab || e.Key == Key.Return) &&
            (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift &&
             uie != null)
        {
            MoveFocusPrevious(uie, (UIElement)sender);
    
            e.Handled = true;
        }
        else if ((e.Key == Key.Tab || e.Key == Key.Return) && uie != null)
        {
            // Normal 'Enter' or 'Tab' key click
            MoveFocusNext(uie, (UIElement)sender);
    
            e.Handled = true;
        }
    }
    

    移动焦点方法:

    private void MoveFocusNext(UIElement uie, UIElement sender)
    {
        if(!uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right)))
        {
            uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); // Move Down
            uie = (UIElement)Keyboard.FocusedElement;
            MoveFocusToFirst(uie, sender); // Move to to first
        }
    }
    
    private void MoveFocusPrevious(UIElement uie, UIElement sender)
    {
        if (!uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left)))
        {
            uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous)); // Move Up
            uie = (UIElement)Keyboard.FocusedElement;
            MoveFocusToLast(uie, sender); // Move focus to last
        }
    }
    
    private void MoveFocusToLast(UIElement uie, UIElement sender)
    {
        bool isLast = false;
    
        // Move right until hitting last item
        while(!isLast)
        {
            // If Focus cannot be moved, it is last item.
            isLast = !uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
            uie = (UIElement)Keyboard.FocusedElement;
        }
    }
    
    private void MoveFocusToFirst(UIElement uie, UIElement sender)
    {
        bool isFirst = false;
    
        // Move left until hitting last item
        while (!isFirst)
        {
            // If Focus cannot be moved, it is last item.
            isFirst = !uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Left)); 
            uie = (UIElement)Keyboard.FocusedElement; 
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 2023-01-29
      • 2018-04-24
      • 1970-01-01
      • 2020-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多