admin管理员组文章数量:1312778
I'm trying to implement an auto-search functionality for a WPF ComboBox, where the combo box filters its items as the user types, and allows them to select from the filtered list. However, after selecting an item from the filtered list, the selected item does not display in the ComboBox.
Expected behavior: When the user starts typing, the ComboBox filters and displays matching items. After selecting an item from the filtered list, the ComboBox should display the selected item in the editable textbox. Problem: The ComboBox behaves as expected when typing, filtering items based on the entered text. But once the user selects a filtered item, it doesn't show up in the ComboBox.
What I've tried: I have implemented custom logic to update the SelectedItem and SearchText properties when the user selects an item. I’ve also added handling for SelectionChanged and PreviewKeyDown events to manage the interaction between the ComboBox and the search functionality. However, the selected value does not display in the ComboBox as expected.
Here’s a simplified version of my code:
xaml:
<ComboBox
x:Name="ComboBoxControl"
Width="500"
Margin="10"
materialDesign:HintAssist.Foreground="DeepPink"
materialDesign:HintAssist.Hint="Select Type"
materialDesign:TextFieldAssist.HasClearButton="True"
IsEditable="True"
IsTextSearchCaseSensitive="False"
IsTextSearchEnabled="False"
ItemsSource="{Binding FilteredItems}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
SelectionChanged="ComboBoxControl_SelectionChanged"
Style="{StaticResource MaterialDesignOutlinedComboBox}"
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />
backened code:
namespace WpfApp1.CustomControls
{
public partial class AutoSearchComboBox : UserControl, INotifyPropertyChanged
{
public ObservableCollection<string> ItemsSource { get; set; }
public ObservableCollection<string> FilteredItems { get; set; } = new ObservableCollection<string>();
private string _selectedItem;
public string SelectedItem
{
get => _selectedItem;
set
{
if (_selectedItem != value)
{
_selectedItem = value;
OnPropertyChanged(nameof(SelectedItem));
if (!_isUpdatingFromCode)
{
SearchText = _selectedItem; // Sync selected item to search text
}
}
}
}
private string _searchText;
public string SearchText
{
get => _searchText;
set
{
if (_searchText != value)
{
_searchText = value;
if (!_isUpdatingFromCode)
{
FilterItems(); // Trigger filtering when SearchText changes
}
OnPropertyChanged(nameof(SearchText));
}
}
}
private bool _isUserTyping = false;
private bool _isUpdatingFromCode = false;
public AutoSearchComboBox()
{
InitializeComponent();
DataContext = this;
Loaded += AutoSearchComboBox_Loaded;
ComboBoxControl.PreviewKeyDown += ComboBoxControl_PreviewKeyDown;
ComboBoxControl.SelectionChanged += ComboBoxControl_SelectionChanged;
}
private void ComboBoxControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isUserTyping && ComboBoxControl.SelectedItem != null && !_isUpdatingFromCode)
{
ComboBoxControl.IsEditable = false;
Dispatcher.BeginInvoke(new Action(() =>
{
SearchText = ComboBoxControl.SelectedItem.ToString(); // Update SearchText
SelectedItem = ComboBoxControl.SelectedItem.ToString(); // Sync SelectedItem
_isUpdatingFromCode = false;
}), System.Windows.Threading.DispatcherPriority.Background);
ComboBoxControl.IsEditable = true;
}
}
private void ComboBoxControl_PreviewKeyDown(object sender, KeyEventArgs e)
{
_isUserTyping = true;
var textBox = ComboBoxControl.Template.FindName("PART_EditableTextBox", ComboBoxControl) as TextBox;
if (textBox != null)
{
if (textBox.SelectionLength > 0) textBox.SelectionLength = 0;
textBox.CaretIndex = textBox.Text.Length;
}
_isUserTyping = false;
}
private void AutoSearchComboBox_Loaded(object sender, RoutedEventArgs e)
{
if (ItemsSource != null)
{
FilteredItems.Clear();
foreach (var item in ItemsSource)
{
FilteredItems.Add(item);
}
}
}
private void FilterItems()
{
if (_isUpdatingFromCode) return;
FilteredItems.Clear();
if (string.IsNullOrWhiteSpace(SearchText))
{
foreach (var item in ItemsSource)
{
FilteredItems.Add(item);
}
}
else
{
foreach (var item in ItemsSource.Where(i => i.StartsWith(SearchText, StringComparison.OrdinalIgnoreCase) || i.Contains(SearchText, StringComparison.OrdinalIgnoreCase)))
{
FilteredItems.Add(item);
}
}
ComboBoxControl.IsDropDownOpen = true;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
本文标签: cWPFIssue with ComboBox Autosearch Filtered Items Not Displayed After SelectionStack Overflow
版权声明:本文标题:c# - WPF : Issue with ComboBox Autosearch: Filtered Items Not Displayed After Selection - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741879486a2402661.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论