代码之家  ›  专栏  ›  技术社区  ›  Joel B Fant

列表框+包装板箭头键导航

  •  5
  • Joel B Fant  · 技术社区  · 16 年前

    我正在尝试实现一个WinForms的等价物 ListView 用它 View 属性设置为 View.List . 从视觉上看,以下工作正常。我的文件名 Listbox 从上到下,然后换行到新列。

    以下是我正在使用的基本XAML:

    <ListBox Name="thelist"
        IsSynchronizedWithCurrentItem="True"
        ItemsSource="{Binding}"
        ScrollViewer.VerticalScrollBarVisibility="Disabled">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel IsItemsHost="True"
                    Orientation="Vertical" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
    

    但是,默认的箭头键导航不换行。如果选择了列中的最后一项,则按向下箭头不会转到下一列的第一项。

    我试过处理 KeyDown 类似事件:

    private void thelist_KeyDown( object sender, KeyEventArgs e ) {
        if ( object.ReferenceEquals( sender, thelist ) ) {
            if ( e.Key == Key.Down ) {
                e.Handled = true;
                thelist.Items.MoveCurrentToNext();
            }
            if ( e.Key == Key.Up ) {
                e.Handled = true;
                thelist.Items.MoveCurrentToPrevious();
            }
        }
    }
    

    这将产生我想要的从最后一列到下一列第一列的行为,但也会在左箭头和右箭头处理中产生奇怪的现象。每当它使用上/下箭头从一列换行到下一列/上一列时,随后使用左箭头键或右箭头键可将所选内容移动到换行前所选项目的左侧或右侧。

    假设列表由字符串“0001”到“0100”填充,每列10个字符串。如果我使用向下箭头键从“0010”转到“0011”,然后按向右箭头键,选择移动到“0020”,就在“0010”的右边。如果选择“0011”,并且我使用向上箭头键将选择移动到“0010”,则按下右箭头键将选择移动到“0021”(在“0011”的右侧),按下左箭头键将选择移动到“0001”。

    任何帮助实现所需的列环绕布局和箭头键导航都将不胜感激。

    (编辑移动到我自己的答案,因为从技术上讲它是一个答案。)

    2 回复  |  直到 14 年前
        1
  •  8
  •   Joel B Fant    14 年前

    结果是当它在我处理 KeyDown 事件,所选内容更改为正确的项目,但重点放在旧项目上。

    这是最新的 按下 埃文森德勒。因为束缚, Items 集合返回实际项目,而不是 ListBoxItem S,所以我得在最后打个电话才能得到 列表项目 我需要打电话 Focus() 在。从最后一项到第一项的包装,反之亦然,可以通过交换 MoveCurrentToLast() MoveCurrentToFirst() .

    private void thelist_KeyDown( object sender, KeyEventArgs e ) {
        if ( object.ReferenceEquals( sender, thelist ) ) {
            if ( thelist.Items.Count > 0 ) {
                switch ( e.Key ) {
                    case Key.Down:
                        if ( !thelist.Items.MoveCurrentToNext() ) {
                            thelist.Items.MoveCurrentToLast();
                        }
                        break;
    
                    case Key.Up:
                        if ( !thelist.Items.MoveCurrentToPrevious() ) {
                            thelist.Items.MoveCurrentToFirst();
                        }
                        break;
    
                    default:
                        return;
                }
    
                e.Handled = true;
                ListBoxItem lbi = (ListBoxItem) thelist.ItemContainerGenerator.ContainerFromItem( thelist.SelectedItem );
                lbi.Focus();
            }
        }
    }
    
        2
  •  4
  •   Bryan Anderson    15 年前

    您应该能够在没有事件侦听器的情况下使用keyboardnavigation.directionalnavigation,例如

    <ListBox Name="thelist"
             IsSynchronizedWithCurrentItem="True"
             ItemsSource="{Binding}"
             ScrollViewer.VerticalScrollBarVisibility="Disabled"
             KeyboardNavigation.DirectionalNavigation="Cycle">