2012-03-04 3 views
0

Google 홈페이지에서 찾을 수있는 복제 자동 완성 기능을 사용하려고합니다. 따라서 텍스트 상자에 입력을 시작하면 제안 목록이 드롭 다운되고 위쪽 또는 아래쪽 화살표 키를 사용하면이 목록을 반복 할 수 있습니다. 나는이 기능으로 꽤 많이있다. 아래에 나열된 코드는 문제를 보여줍니다.ListBox의 ListBoxItem에 초점을 맞추면 위에있는 ListBoxItem이 선택됩니다.

처음 입력을 시작하고 추천 목록이 표시되면 텍스트 상자에 여전히 포커스가있는 상태에서 위쪽 화살표 키를 누르면 포커스 목록의 마지막 항목에 초점이 맞춰지고 선택됩니다.

아래 예제에서 마지막 항목의 두 번째 항목이 선택되며 '나는 왜 그런지 짐작할 수 없습니다. 필자는 필자의 예제에서 제안 사항을 코딩하여 입력 할 필요가 없다. 위쪽 화살표 키를 누르면 문제가 나타납니다.

<Window x:Class="MyTestApplication.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" 
     Height="350" 
     Width="525" 
     Loaded="Window_Loaded"> 
    <StackPanel> 
     <TextBox x:Name="nameTextBox" 
       Text="hello world!" 
       PreviewKeyDown="nameTextBox_PreviewKeyDown" /> 
     <ListBox x:Name="suggestionListBox" 
       DisplayMemberPath="Name" 
       SelectionChanged="suggestionListBox_SelectionChanged" 
       PreviewKeyDown="suggestionListBox_PreviewKeyDown" /> 
     <Label x:Name="output" /> 
    </StackPanel> 
</Window> 


using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Input; 

namespace MyTestApplication 
{ 
    public partial class MainWindow : Window 
    { 
     private const int NOT_SELECTED = -1; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      suggestionListBox.ItemsSource = new[] 
      { 
       new { Name = "aaaaaa"}, 
       new { Name = "bbbbbbbb"}, 
       new { Name = "cccc"}, 
       new { Name = "ddddd"}, 
       new { Name = "eeeeee"}, 
       new { Name = "fffffffff"} 
      }; 

      output.Content = suggestionListBox.SelectedIndex.ToString(); 
     } 

     private void Window_Loaded(object sender, RoutedEventArgs e) 
     { 
      nameTextBox.Focus(); 
     } 

     private void nameTextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
     { 
      if (e.Key == Key.Down) 
      { 
       suggestionListBox.Focus(); 
      } 

      if (e.Key == Key.Up) 
      { 
       var listBoxItem = (ListBoxItem)suggestionListBox 
         .ItemContainerGenerator 
         .ContainerFromIndex(suggestionListBox.Items.Count - 1); 

       var result = listBoxItem.Focus(); 
      } 
     } 

     private void suggestionListBox_PreviewKeyDown(object sender, KeyEventArgs e) 
     { 
      if ( (e.Key == Key.Up && suggestionListBox.SelectedIndex == 0) 
       || (e.Key == Key.Down && suggestionListBox.SelectedIndex == suggestionListBox.Items.Count - 1)) 
      { 
       suggestionListBox.SelectedIndex = NOT_SELECTED; 
       nameTextBox.Focus(); 
      } 
     } 

     private void suggestionListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      output.Content = suggestionListBox.SelectedIndex.ToString(); 
     } 
    } 
} 

목록 상자에서 선택한 인덱스를 사용하여 시도했지만 목록 상자에서 포커스 메서드를 호출하면 선택한 인덱스가 0으로 설정됩니다. 이것이 내가 제안 목록에서 마지막 목록 상자 항목을 찾은 다음 초점을 적용하는 이유이지만 위 항목을 강조 표시합니다. 희망이 의미가 있습니다. 문제를 시연하려면 새 WPF 프로젝트를 만들고 위 코드를 MainWindow.xaml 및 MainWindow.Xaml.cs에 복사하여 붙여넣고 응용 프로그램을 실행하면됩니다. 모든 것이 드러날 것입니다.

도움이나 표시가 크게 접수됩니다.

우수

모하마드.

+0

은 nameTextBox_PreviewKeyDown 방법에 중단 점을 넣어보십시오. 그것은 단지 한 번의 키를 한 번만 불렀습니까? –

답변

1

PreviewKeyDown 이벤트가 부모 컨트롤에서 하위 컨트롤로 터널링되며, 터널링을 더 이상 원하지 않는 경우에는 args의 handles 속성을 true로 설정하여 이벤트를 처리해야합니다 이 e.Handled = true.

그래서,이 당신을 위해 일한다 -

private void nameTextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Down) 
    { 
     suggestionListBox.Focus(); 
    } 

    if (e.Key == Key.Up) 
    { 
     var listBoxItem = (ListBoxItem)suggestionListBox 
         .ItemContainerGenerator 
         .ContainerFromIndex(suggestionListBox.Items.Count - 1); 

     suggestionListBox.SelectedIndex = suggestionListBox.Items.Count - 1; 
     listBoxItem.Focus(); 
     e.Handled = true; 
    } 
} 
+0

감사합니다. 잘됐다. – dezzy

관련 문제