用于WPF的自动完成combobox
我需要一个用于WPF C#的自动完成combobox。 我尝试了几种方法,但没有任何效果。 例如,我尝试过一个combobox:
Names
是一个字符串列表:Peter John,John,John Doe,Cathy,Howard,John Richards等等
如果你输入一个免费精选名字大全,例如John,combobox应该扩展,我应该看到
但这不起作用。 我怎样才能做到这一点?
使用PreviewTextInput事件进行过滤和显示下拉,如下所示:
private void ComboBox_TextInput_1(object sender, TextCompositionEventArgs e) { cmbperson.IsDropDownOpen = true; cmbperson.ItemsSource = DataBase.Persons.Where(p => p.Name.Contains(e.Text)).ToList(); }
我建议您使用自动完成的控件而不是combobox。 许多公司提供这样的控制, 这个控制是免费的,并被认为是好的
经过大量的摆弄,我已经设法找到了一个完整的,有效的解决方案。 (或者似乎是这样。)
步骤1.修改XAML标记
你需要像这样修改你的ComboBox:
即。 禁用默认文本搜索,并添加将负责用户添加,删除和粘贴文本的事件处理程序。
步骤2.添加一个辅助函数,它将获得ComboBox的内部TextBox(因为WPF)
PreviewTextInput_EnhanceComboSearch
和Pasting_EnhanceComboSearch
完全正常工作,您需要访问ComboBox的插入符号。 不幸的是,要做到这一点,你需要遍历,呃,视觉树( 帽子提示到马特汉密尔顿 )。 您可以在扩展方法中执行此操作,但我在Page
类中使用了静态方法:
public static T GetChildOfType(DependencyObject depObj) where T : DependencyObject { if (depObj == null) return null; for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { var child = VisualTreeHelper.GetChild(depObj, i); var result = (child as T) ?? GetChildOfType (child); if (result != null) return result; } return null; }
第3步。实现事件处理程序
请注意我用过
s => s.IndexOf(e.Text, StringComparison.InvariantCultureIgnoreCase) != -1
这相当于不区分大小写的s => s.Contains(e.Text)
检查。 记得改变那部分以满足您的需求。
步骤3.a触发用户在ComboBox内键入的搜索
运行PreviewTextInput
处理程序时,ComboBox中的.Text
属性包含修改之前的文本。 因此,我们需要使用GetChildOfType
方法获取ComboBox的内部TextBox以获取其插入符,因此我们知道插入的键入字符的确切位置。
private void PreviewTextInput_EnhanceComboSearch(object sender, TextCompositionEventArgs e) { ComboBox cmb = (ComboBox)sender; cmb.IsDropDownOpen = true; if (!string.IsNullOrEmpty(cmb.Text)) { string fullText = cmb.Text.Insert(GetChildOfType(cmb).CaretIndex, e.Text); cmb.ItemsSource = Names.Where(s => s.IndexOf(fullText, StringComparison.InvariantCultureIgnoreCase) != -1).ToList(); } else if (!string.IsNullOrEmpty(e.Text)) { cmb.ItemsSource = Names.Where(s => s.IndexOf(e.Text, StringComparison.InvariantCultureIgnoreCase) != -1).ToList(); } else { cmb.ItemsSource = Names; } }
步骤3.b触发用户粘贴到ComboBox的搜索
DataObject.Pasting
处理程序的行为方式与PreviewTextInput
hanlder类似,因此我们需要再次使用插入符号。
private void Pasting_EnhanceComboSearch(object sender, DataObjectPastingEventArgs e) { ComboBox cmb = (ComboBox)sender; cmb.IsDropDownOpen = true; string pastedText = (string)e.DataObject.GetData(typeof(string)); string fullText = cmb.Text.Insert(GetChildOfType(cmb).CaretIndex, pastedText); if (!string.IsNullOrEmpty(fullText)) { cmb.ItemsSource = Names.Where(s => s.IndexOf(fullText, StringComparison.InvariantCultureIgnoreCase) != -1).ToList(); } else { cmb.ItemsSource = Names; } }
步骤3.c触发搜索用户删除ComboBox内的文本(并按下Space,因为WPF)
当用户按下Delete或Backspace时,将触发此操作。
还有Space,因为PreviewTextInput
会忽略Space,所以在PreviewTextInput
中很难从“John Doe”和“John Richards”中过滤掉“John”。
private void PreviewKeyUp_EnhanceComboSearch(object sender, KeyEventArgs e) { if (e.Key == Key.Back || e.Key == Key.Delete) { ComboBox cmb = (ComboBox)sender; cmb.IsDropDownOpen = true; if (!string.IsNullOrEmpty(cmb.Text)) { cmb.ItemsSource = Names.Where(s => s.IndexOf(cmb.Text, StringComparison.InvariantCultureIgnoreCase) != -1).ToList(); } else { cmb.ItemsSource = Names; } } }
……这应该足够了。
我为WPF
创建了一个可以帮助你的自动完成function。 请点击以下链接到github: https : //github.com/rhpontes/AutocompleteWpf
我希望它对你有所帮助。
在XAML中,您应该设置IsEditable = True并为PreviewKeyDown事件添加处理程序:
上述就是C#学习教程:用于WPF的自动完成combobox分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
private void ComboBox_PreviewKeyDown(object sender, KeyEventArgs e) { var cmb = (ComboBox)sender; cmb.IsDropDownOpen = true; var textbox = cmb.Template.FindName("PART_EditableTextBox", cmb) as TextBox; cmb.ItemsSource = CurrentStorage.Organisations.Where(p => string.IsNullOrEmpty(cmb.Text) || p.Name.ToLower().Contains(textbox.Text.ToLower())).ToList(); }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/989605.html