2008-09-25 112 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">