2008-09-25 111 views
5

我试图实现相当于WinForms ListView及其View属性设置为View.List。从视觉上看,以下工作正常。我的Listbox中的文件名从顶部到底部,然后换行到新列。ListBox + WrapPanel箭头键导航

这里是基本的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”。

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

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

回答

8

事实证明,当它在包装处理我的KeyDown情况下,选择更改为正确项左右,但重点是在老项目。

这是更新的KeyDown事件处理程序。因为绑定,Items集合返回我的实际项目而不是ListBoxItem s,所以我必须在接近结束处接打电话以获取我需要拨打Focus()的实际ListBoxItem。将最后一个项目包装到第一个,反之亦然可以通过交换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(); 
     } 
    } 
} 
+0

太棒了,这对我有很大的帮助。 ;) – Inferis 2009-03-16 20:55:36

4

您应该能够使用KeyboardNavigation.DirectionalNavigation做到这一点没有事件侦听器,例如

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