列表框+ WrapPanel箭头键导航(ListBox+WrapPanel arrow key na

2019-08-02 19:53发布

我想实现的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”。

实现任何所需的列,包裹布局和方向键的导航帮助,将不胜感激。

(编辑搬到我自己的答案,因为它在技术上是一个答案。)

Answer 1:

事实证明,当它在我的搬运的回绕KeyDown事件,选择更改为正确的项目,但重点是在老项目。

这里是更新KeyDown事件处理程序。 因为绑定的,该Items集合返回我的实际项目,而不是ListBoxItem S,所以我必须做接近尾声时调用来获取实际ListBoxItem我需要调用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();
        }
    }
}


Answer 2:

你应该能够做到这一点,而无需使用KeyboardNavigation.DirectionalNavigation,例如事件监听器

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


文章来源: ListBox+WrapPanel arrow key navigation