2017-07-21 14 views
2

私は私のカスタムコンボボックス持っている:ナビゲーションWPFで検索コンボボックス

public class CustomComboBox : ComboBox 
{ 
    protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
    { 
     // allow to go into items using up and down arrows without causing the text change 
     e.Handled = true; 
    } 
} 

とXAMLのように:ウィンドウの

<Window> 
    <Grid> 
     <wpfApplication1:CustomComboBox IsEditable="True" 
        Width="200" 
        Height="25" 
        IsTextSearchEnabled="False" 
        StaysOpenOnEdit="True" 
        x:Name="cb" 
        PreviewTextInput="Cb_OnPreviewTextInput" 
        ItemsSource="{Binding Projects}" 
        Text="{Binding Text}" 
        SelectionChanged="Cb_OnSelectionChanged"> 
      <ComboBox.ItemsPanel> 
       <ItemsPanelTemplate> 
        <VirtualizingStackPanel /> 
       </ItemsPanelTemplate> 
      </ComboBox.ItemsPanel> 
     </wpfApplication1:CustomComboBox> 
    </Grid> 
</Window> 

コード:

Cb_OnPreviewTextInputが呼び出され
public partial class MainWindow : INotifyPropertyChanged 
{ 
    public ICollectionView Projects { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = this; 

     ObservableCollection = new ObservableCollection<string>(Enumerable.Range(1, 1000).Select(i => $"Item {i}")); 

     Projects = CollectionViewSource.GetDefaultView(ObservableCollection); 
    } 

    private string _text; 
    public ObservableCollection<string> ObservableCollection { get; set; } 

    public string Text 
    { 
     get { return _text; } 
     set 
     { 
      if (_text != value) 
      { 
       _text = value; 
       OnPropertyChanged(); 

       Projects.Filter = f => 
       { 
        var search = Text.ToLower(); 
        var item = f.ToString().ToLower(); 

        return item.Contains(search); 
       }; 
      } 
     } 
    } 

    private void Cb_OnPreviewTextInput(object sender, TextCompositionEventArgs e) 
    { 
     cb.IsDropDownOpen = true; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

を私はIsDropdownOpen = trueと設定しました。最初の文字(最初の文字を入力した後)では、リストの最初の項目が選択され、関連する矢印を使用して上下に移動できますが、キャレットはまだTextBoxです。

私はその時点で入力を続けても、今度は上下にナビゲートすることができません。この時点では、ScrollViewer全体がフォーカスを取得しています。一番上ですが、1ではありません。私はポップアップを閉じなければなりません。エスケープを押してから1文字を入力してもう一度開いて、再び上下に行くことができます。

私はPageUpを押した後も最初の項目も選択されていることに気づいたので、コードではそのことを模倣しようとしましたが、運はありません。

誰もが上/下をナビゲートして問題なく入力できるようにするためにここで何をすべきかを知っていますか?

私はのようなものを試してみました:

protected override void OnPreviewKeyDown(KeyEventArgs e) 
{ 
    if (_popup != null && e.Key == Key.Up || e.Key == Key.Down) 
    { 
     Dispatcher.BeginInvoke(DispatcherPriority.Input, 
     new Action(() => 
     { 
      var c = _popup.Child; 
      var vs = c.GetChildOfType<VirtualizingStackPanel>(); 
      vs.PageUp(); 
      vs.Focus(); 
      Keyboard.Focus(vs); 
     })); 
    } 

    base.OnPreviewKeyDown(e); 
} 

しかし、それは動作しませんでした。

答えて

0

ListViewの新しいテンプレートを作成して終了しました。

プラスカスタム・ロジックOnPreviewKeyDown内側:

if (e.Key == Key.Up || e.Key == Key.Down) 
{ 
    listView.Focus(); 
    listView.Items.MoveCurrentTo(listView.SelectedItem); 

    if (e.Key == Key.Up) 
     listView.Items.MoveCurrentToPrevious(); 
    else 
     listView.Items.MoveCurrentToNext(); 

    listView.SelectedItem = listView.Items.CurrentItem; 
    listView.ScrollIntoView(listView.Items.CurrentItem); 

    e.Handled = true; 

    return; 
} 

うまく機能;)

関連する問題