Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF组合框搜索键入速度_Wpf_Input_Combobox - Fatal编程技术网

WPF组合框搜索键入速度

WPF组合框搜索键入速度,wpf,input,combobox,Wpf,Input,Combobox,我有一个WPF组合框 <ComboBox BorderThickness="0" Name="cmb_songs_head" HorizontalAlignment="Right" SelectedItem="{Binding Path=T.SelectedSong, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Path=T.SelectedSet.Songs, UpdateSourceT

我有一个WPF组合框

<ComboBox BorderThickness="0" Name="cmb_songs_head" HorizontalAlignment="Right" SelectedItem="{Binding Path=T.SelectedSong, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Path=T.SelectedSet.Songs, UpdateSourceTrigger=PropertyChanged}" />
因此,当我键入
H
时,选择第一项,
Ho
选择第二项,
Holl
选择第三项

但是,我的程序的用户抱怨说,他们通常打字太慢,因此他们最后键入
Hol
,选择
Hold
,然后是
l
,选择
Lead
;而不是将其视为
Hollow
的一个输入

有没有办法延长单词之间的超时时间?

您可以在绑定
组合框时进行设置。选择editem

以下示例将绑定延迟设置为1500ms。延迟结束前发生的绑定目标或源的每次更改都将重置延迟计时器:

<ComboBox Name="cmb_songs_head" 
          StaysOpenOnEdit="True"
          IsEditable="True"
          SelectedItem="{Binding T.SelectedSong, Delay=1500}"
          ItemsSource="{Binding T.SelectedSet.Songs}" />
代码隐藏

private void EditTextBox _OnPreviewKeyUp(object sender, KeyEventArgs e)
{
  var editTextBox = e.OriginalSource as TextBox;
  var comboBox = sender as ComboBox;

  switch (e.Key)
  {
    case Key.Back:
    {
      MainWindow.FilterComboBoxItemsSource(sender as ComboBox, editTextBox.Text, editTextBox);
      int selectionStart = comboBox.SelectedItem == null
        ? editTextBox.CaretIndex
        : Math.Max(0, editTextBox.SelectionStart - 1);
      int selectionLength = comboBox.SelectedItem == null 
        ? 0 
        : editTextBox.Text.Length - selectionStart;
      editTextBox.Select(selectionStart, selectionLength);
      break;
    }
    case Key.Space:
    {
      MainWindow.FilterComboBoxItemsSource(sender as ComboBox, editTextBox.Text, editTextBox);
      break;
    }
    case Key.Delete:
    {
      int currentCaretIndex = editTextBox.CaretIndex;
      MainWindow.FilterComboBoxItemsSource(sender as ComboBox, editTextBox.Text, editTextBox);
      editTextBox.CaretIndex = currentCaretIndex;
      break;
    }
  }
}

private void ComboBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
  e.Handled = true;

  var editTextBox = e.OriginalSource as TextBox;
  string oldText = editTextBox.Text.Substring(0, editTextBox.SelectionStart);
  string newText = oldText + e.Text;

  FilterComboBoxItemsSource(sender as ComboBox, newText, editTextBox);
}

private void FilterComboBoxItemsSource(ComboBox comboBox, string predicateText, TextBox editTextBox)
{
  ICollectionView collectionView = CollectionViewSource.GetDefaultView(comboBox.ItemsSource);
  if (!string.IsNullOrWhiteSpace(predicateText) 
    && !collectionView.SourceCollection
      .Cast<string>()
      .Any(item => item.StartsWith(predicateText, StringComparison.OrdinalIgnoreCase)))
  {
    int oldCaretIndex = editTextBox.CaretIndex == editTextBox.Text.Length
      ? predicateText.Length
      : editTextBox.CaretIndex;
    editTextBox.Text = predicateText;
    editTextBox.CaretIndex = oldCaretIndex;
    return;
  }

  collectionView.Filter = item => (item as string).StartsWith(string.IsNullOrWhiteSpace(predicateText) 
    ? string.Empty 
    : predicateText, StringComparison.OrdinalIgnoreCase);

  collectionView.MoveCurrentToFirst();
  editTextBox.Text = collectionView.CurrentItem as string;
  editTextBox.Select(predicateText.Length, editTextBox.Text.Length - predicateText.Length);
}
private void EditTextBox\u OnPreviewKeyUp(对象发送方,KeyEventArgs e)
{
var editTextBox=e.OriginalSource as TextBox;
var comboBox=发送方作为组合框;
开关(电子钥匙)
{
case Key.Back:
{
main window.filterComboxItemsSource(发送者作为组合框,editTextBox.Text,editTextBox);
int selectionStart=comboBox.SelectedItem==null
?editTextBox.CaretIndex
:Math.Max(0,editTextBox.SelectionStart-1);
int-selectionLength=comboBox.SelectedItem==null
? 0 
:editTextBox.Text.Length-选择开始;
编辑文本框。选择(selectionStart,selectionLength);
打破
}
大小写键。空格:
{
main window.filterComboxItemsSource(发送者作为组合框,editTextBox.Text,editTextBox);
打破
}
大小写键。删除:
{
int currentCaretIndex=editTextBox.CaretIndex;
main window.filterComboxItemsSource(发送者作为组合框,editTextBox.Text,editTextBox);
editTextBox.CaretIndex=currentCaretIndex;
打破
}
}
}
private void组合框\u on预览输出(对象发送者,文本合成目标e)
{
e、 已处理=正确;
var editTextBox=e.OriginalSource as TextBox;
字符串oldText=editTextBox.Text.Substring(0,editTextBox.SelectionStart);
字符串newText=oldText+e.Text;
FilterComboxItemsSource(发件人为组合框、新文本、编辑文本框);
}
专用无效筛选器ComboxItemsSource(组合框组合框、字符串谓词文本、文本框编辑文本框)
{
ICollectionView collectionView=CollectionViewSource.GetDefaultView(comboBox.ItemsSource);
如果(!string.IsNullOrWhiteSpace(谓词文本)
&&!collectionView.SourceCollection
.Cast()
.Any(item=>item.StartsWith(谓词文本、StringComparison.OrdinalIgnoreCase)))
{
int oldCaretIndex=editTextBox.CaretIndex==editTextBox.Text.Length
?谓词文本长度
:editTextBox.CaretIndex;
editTextBox.Text=谓词文本;
editTextBox.CaretIndex=oldCaretIndex;
回来
}
collectionView.Filter=item=>(项作为字符串)。StartsWith(string.IsNullOrWhiteSpace(谓词文本)
?字符串。空
:predicateText,StringComparison.OrdinalIgnoreCase);
collectionView.MoveCurrentToFirst();
editTextBox.Text=collectionView.CurrentItem作为字符串;
选择(predicateText.Length,editTextBox.Text.Length-predicateText.Length);
}

感谢您提供简化绑定的提示。延迟并没有达到我想要的效果——我尝试将它设置为30000(这应该给我30秒的时间来键入单词中的下一个字母);但这并没有改变我找到答案的时间——看这对我有用。将延迟设置为30000,在按下一个键后给我30秒的时间,直到当前项目实际提交。我明白了。您正在使用不同的配置。您应该将
ComboBox.IsEditable
ComboBox.StaysOpenOnEdit
属性设置为
true
。与Binding.Delay一起,您将体验到预期的行为。我假设你已经设置了这些属性。每当我想在
组合框中键入内容时
我自然会将
设置为可编辑的
,这就是为什么我没有问你这个问题。但我不希望它是可编辑的。它是用户从中选择的只读列表
<ComboBox ItemsSource="{Binding T.SelectedSet.Songs}" 
          SelectedItem="{Binding T.SelectedSong, Delay=5000}"
          StaysOpenOnEdit="True" 
          IsEditable="True" 
          TextBoxBase.PreviewKeyUp="EditTextBox_OnPreviewKeyUp"
          PreviewTextInput="ComboBox_OnPreviewTextInput" />
private void EditTextBox _OnPreviewKeyUp(object sender, KeyEventArgs e)
{
  var editTextBox = e.OriginalSource as TextBox;
  var comboBox = sender as ComboBox;

  switch (e.Key)
  {
    case Key.Back:
    {
      MainWindow.FilterComboBoxItemsSource(sender as ComboBox, editTextBox.Text, editTextBox);
      int selectionStart = comboBox.SelectedItem == null
        ? editTextBox.CaretIndex
        : Math.Max(0, editTextBox.SelectionStart - 1);
      int selectionLength = comboBox.SelectedItem == null 
        ? 0 
        : editTextBox.Text.Length - selectionStart;
      editTextBox.Select(selectionStart, selectionLength);
      break;
    }
    case Key.Space:
    {
      MainWindow.FilterComboBoxItemsSource(sender as ComboBox, editTextBox.Text, editTextBox);
      break;
    }
    case Key.Delete:
    {
      int currentCaretIndex = editTextBox.CaretIndex;
      MainWindow.FilterComboBoxItemsSource(sender as ComboBox, editTextBox.Text, editTextBox);
      editTextBox.CaretIndex = currentCaretIndex;
      break;
    }
  }
}

private void ComboBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
  e.Handled = true;

  var editTextBox = e.OriginalSource as TextBox;
  string oldText = editTextBox.Text.Substring(0, editTextBox.SelectionStart);
  string newText = oldText + e.Text;

  FilterComboBoxItemsSource(sender as ComboBox, newText, editTextBox);
}

private void FilterComboBoxItemsSource(ComboBox comboBox, string predicateText, TextBox editTextBox)
{
  ICollectionView collectionView = CollectionViewSource.GetDefaultView(comboBox.ItemsSource);
  if (!string.IsNullOrWhiteSpace(predicateText) 
    && !collectionView.SourceCollection
      .Cast<string>()
      .Any(item => item.StartsWith(predicateText, StringComparison.OrdinalIgnoreCase)))
  {
    int oldCaretIndex = editTextBox.CaretIndex == editTextBox.Text.Length
      ? predicateText.Length
      : editTextBox.CaretIndex;
    editTextBox.Text = predicateText;
    editTextBox.CaretIndex = oldCaretIndex;
    return;
  }

  collectionView.Filter = item => (item as string).StartsWith(string.IsNullOrWhiteSpace(predicateText) 
    ? string.Empty 
    : predicateText, StringComparison.OrdinalIgnoreCase);

  collectionView.MoveCurrentToFirst();
  editTextBox.Text = collectionView.CurrentItem as string;
  editTextBox.Select(predicateText.Length, editTextBox.Text.Length - predicateText.Length);
}