c# - 当同一组合框中的文本更改时如何填充组合框项目
问题描述
我正在尝试将 textchanges 事件实现到组合框,以便项目根据在同一组合框中输入的值进行更改。
这是我的 XAML
<ComboBox Name="ComboBoxRoleNameDescEdit" IsEditable="True" TextBoxBase.TextChanged="ComboBoxRoleNameDescEdit_TextChanged"/>
这是代码隐藏:
private void ComboBoxRoleNameDescEdit_TextChanged(object sender, TextChangedEventArgs e)
{
try
{
ComboBoxRoleNameDescEdit.Items.Clear();
using (var Connect = new SqlConnection(connstr))
{
Connect.Open();
using (var Command = new SqlCommand("[dbo].[spParametresRolesTb_FillRoleIdComboBox]", Connect))
{
Command.CommandType = CommandType.StoredProcedure;
Command.Parameters.Add("@search", SqlDbType.VarChar).Value = ComboBoxRoleNameDescEdit.Text;
Command.Parameters.Add("@entity_id", SqlDbType.VarChar).Value = LoggedInData.LoggedInstitutionId;
SqlDataReader dr = Command.ExecuteReader();
while (dr.Read())
{
string classes = dr.GetString(0);
ComboBoxRoleNameDescEdit.Items.Add(classes);
}
dr.Close();
}
Connect.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
我遇到的问题是,因为我需要在每个输入处刷新项目列表,由于这段代码“ComboBoxRoleNameDescEdit.Items.Clear();”,输入本身正在被清除。实际上,只有第一个输入会被自动清除,其余的输入不会。
知道如何克服这个问题吗?
解决方案
首先,不要ItemsControl
直接操作。对源集合即数据模型进行操作。您还需要在ComboBox
.
视图模型.cs
class ViewModel
{
public ObservableCollection<string> Classes { get; set; }
public ViewModel()
{
this.Classes = new ObservableCollection<string>();
}
public async Task FilterItemsAsync(string predicate, CancellationToken cancellationToken)
{
using (var connection = new SqlConnection(connstr))
{
connection.OpenAsync(cancellationToken);
using (var command = new SqlCommand("[dbo].[spParametresRolesTb_FillRoleIdComboBox]", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@search", SqlDbType.VarChar).Value = predicate;
command.Parameters.Add("@entity_id", SqlDbType.VarChar).Value = LoggedInData.LoggedInstitutionId;
using (SqlDataReader dataReader = await command.ExecuteReaderAsync(cancellationToken))
{
this.Classes.Clear();
while (await dataReader.ReadAsync(cancellationToken))
{
string classes = dataReader.GetString(0);
this.Classes.Add(classes);
}
}
}
}
}
}
主窗口.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<ComboBox IsTextSearchEnabled="False"
IsEditable="True"
ItemsSource="{Binding Classes}"
TextBoxBase.TextChanged="ComboBox_TextChanged" />
</Window>
主窗口.xaml.cs
partial class MainWindow : Window
{
private DispatcherTimer DelayTimer { get; set; }
private CancellationTokenSource CancellationTokenSource { get; set; }
private string FilterPredicate { get; set; }
private bool IsFilterExecuting { get; set; }
public MainWindow()
{
InitializeDelayTimer();
this.FilterPredicate = string.Empty;
}
private void InitializeDelayTimer()
{
this.DelayTimer = new DispatcherTimer();
this.DelayTimer.Tick += FilterItemsAsync_OnTimerElapsed;
this.DelayTimer.Interval = TimeSpan.FromMilliseconds(800);
}
private void ComboBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (!(e.OriginalSource is TextBox textBox))
{
return;
}
HandleTimer();
TryCancelRunningFilter();
this.FiterPredicate = textBox.Text;
}
private async void FilterItemsAsync_OnTimerElapsed(object sender, EventArgs e)
{
this.IsFilterExecuting = true;
var viewModel = this.DataContext as ViewModel;
try
{
this.CancellationTokenSource = new CancellationTokenSource();
await viewModel.FilterItemsAsync(this.FiterPredicate, this.CancellationTokenSource.Token);
}
catch (OperationCanceledException) {}
finally
{
this.DelayTimer.Stop();
this.CancellationTokenSource.Dispose();
this.IsFilterExecuting = false;
}
}
private void HandleTimer()
{
// Start or reset the timer interval
this.DelayTimer.Start();
}
private bool TryCancelRunningFilter()
{
if (this.IsFilterExecuting)
{
this.CancellationTokenSource?.Cancel();
return true;
}
return false;
}
}
您当前的实现效率不高,并且提供了糟糕的用户体验。在每次按键时,事件处理程序可能会读取大量数据,这将冻结 UI。我推荐一种异步方法。甚至可能添加一些延迟,以便在键入单词时并非每次按键都会触发过滤器。
推荐阅读
- flutter - Flutter:检测多个小部件上的点击
- java - 如何在方法中流式传输 Java List (Varargs) 的值?
- c# - ASP.NET Core MVC,设置线程文化没有效果
- c# - ObservableCollection 和 INotifyPropertyChanged 的 WPF MVVM 问题
- android - 将 Parse 查询数据从辅助类返回到我的活动
- java - 在 GraphQL (Apollo) 中转换 InputType 对象
- laravel - Laravel:每个外键的唯一外键(user_id)
- c - 二进制插值搜索找不到我正在寻找的数字 (C)
- python - 如何解析“UTC+01:00”格式的时区
- oracle - 如何在 clob 中找到一段文本并用所需的文本包装它?