WPF组合框搜索键入速度
我有一个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
<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);
}