Я использую скрытый TextBox, который ненадолго появляется во время набора текста, сбрасывается через пару секунд и очищается, чтобы он не пытался сопоставить свое содержимое после истечения таймера.Человек наберет ListBox, и его событие KeyUp
заполнит TextBox из-за привязки к SearchText
.Когда SearchText
заполнен, он запускает MyFilteredItems()
, чтобы выполнить сопоставление между этим текстом и ListBox.Затем, если человек нажмет Enter, выделение перейдет в другой TextBox (не указанный в XAML, но предоставляется как закомментированный в коде) и будет очищен от lstPickList
.Затем TextBox очищается и таймер сбрасывается.
XAML:
<TextBox Name="txtPicker" IsReadOnly="True" Foreground="LightGreen" FontFamily="Consolas" Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<ListBox Name="lstPickList" Grid.Row="1" ItemsSource="{Binding MyFilteredItems}" KeyUp="lstPickList_KeyUp"></ListBox>
И затем это соответствующий код:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Timer t = new Timer();
public System.Windows.Threading.DispatcherTimer tCleanup =
new System.Windows.Threading.DispatcherTimer();
private string _searchText;
public string SearchText
{
get { return _searchText; }
set
{
_searchText = value;
OnPropertyChanged("SearchText");
OnPropertyChanged("MyFilteredItems");
}
}
public List<string> MyItems { get; set; }
public IEnumerable<string> MyFilteredItems
{
get
{
if (SearchText == null) return MyItems;
return MyItems.Where(x => x.ToUpper().StartsWith(SearchText.ToUpper()));
}
}
public MainWindow()
{
InitializeComponent();
MyItems = new List<string>() { "ABC", "DEF", "GHI" };
this.DataContext = this;
t.Interval = 1000;
t.Elapsed += new ElapsedEventHandler(timerCounter);
tCleanup.Interval = new TimeSpan(0,0,1);
tCleanup.Tick += new EventHandler(cleanupCounter_Tick);
txtPicker.Visibility = Visibility.Collapsed;
tCleanup.Start();
}
private static int counter = 0;
protected void timerCounter(object sender, ElaspedEventArgs e)
{
counter++;
}
protected void cleanupCounter_Tick(object sender, EventArgs e)
{
if (counter > 2 && txtPicker.Visibility == Visibility.Visible)
txtPicker.Visibility = Visibility.Collapsed;
}
private void lstPickList_KeyUp(object sender, KeyEventArgs e)
{
ListBox lst = (ListBox)sender;
string strg = Convert.ToString(e.Key.ToString().Replace("D",""));
if (counter < 2)
{
txtPicker.Visibility = Visibility.Visible;
t.Start();
if (strg == "Return")
{
txtPicker.Text += "{Enter}";
SearchText += "{Enter}";
}
else
{
txtPicker.Text += strg;
SearchText += strg;
}
}
else
{
SearchText = strg;
txtPicker.Text = strg;
t.Stop();
counter = 0;
t.Start();
}
if (strg == "Return")
{
// This next line would be if you had a "selected items" ListBox to store the item
// lstSelectedList.Items.Add(lstPickList.SelectedItem);
lstPickList.Items.Remove(lstPickList.SelectedItem);
t.Stop();
txtPicker.Visibility = Visibility.Collapsed;
counter = 0;
txtPicker.Text = String.Empty;
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string name)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}