【发布时间】:2022-01-08 15:59:27
【问题描述】:
我的应用程序中有一个组合框,根据您可以在文本字段中输入的搜索文本,异步加载项目。
这工作正常,但每次在更新组合框的数据源期间自动选择第一项的文本。
这会导致意外行为,因为我需要让用户输入的搜索文本留在组合框的文本字段中,直到用户完成选择并且不会自动用第一个条目覆盖文本。
这是我的代码:
public partial class ProductGroupDescription : UserControl, Interfaces.TabPages.ITabPageProductGroupDescription
{
private Services.IProductGroupDescriptionService _ApplicationService;
public BindingList<ProductGroup> ProductGroups { get; set; } = new BindingList<ProductGroup>();
public string ProductGroupSearchText { get; set; } = string.Empty;
public ProductGroupDescription(Services.IProductGroupDescriptionService applicationService)
{
InitializeComponent();
InitialSetupControls();
_ApplicationService = applicationService;
}
public void InitialSetupControls()
{
var pgBindingSource = new BindingSource();
pgBindingSource.DataSource = ProductGroups;
Cbo_ProductGroup.DataSource = pgBindingSource.DataSource;
Cbo_ProductGroup.DataBindings.Add("Text", ProductGroupSearchText, "");
}
private async void Cbo_ProductGroup_TextChanged(object sender, EventArgs e)
{
if (Cbo_ProductGroup.Text.Length >= 2)
{
ProductGroupSearchText = Cbo_ProductGroup.Text;
Cbo_ProductGroup.SelectedIndex = -1;
bool withStopFlagged = Chk_StopFlag_PGs_Included.Checked;
List<ProductGroup> list = await _ApplicationService.GetProductGroupBySearchString(ProductGroupSearchText, withStopFlagged);
if (list != null && list.Count > 0)
{
ProductGroups.Clear();
list.ForEach(item => ProductGroups.Add(item));
Cbo_ProductGroup.DroppedDown = Cbo_ProductGroup.Items.Count > 0 && Cbo_ProductGroup.Focused;
}
}
}
}
我尝试设置Cbo_ProductGroup.SelectedIndex = -1,但这并不能解决我的问题。
我也在 SO 上看到了这个:Prevent AutoSelect behavior of a System.Window.Forms.ComboBox (C#)
但是对于这个问题真的没有更简单的解决方案吗?
【问题讨论】:
-
您是否尝试制作由数据库驱动的自动完成功能?
-
这会导致意外行为 - 通常在 winforms 中,如果我们以编程方式设置文本框的文本但又不想触发文本更改处理程序,我们也删除事件处理程序,执行操作并恢复处理程序,或者(我的偏好)我们设置一些 bool "ignoreTextChanged" true 并且在 TextChanged 处理程序中,我们做的第一件事是检查 bool 并将其设置为 false 并返回,如果它是 true
-
@CaiusJard 第一个问题。我不想提前将所有数据加载到控件中然后使用自动完成,因为我们里面有很多数据。通过给定的文本输入加载它们是有意义的。
-
@CaiusJard 对于您的第二条评论:我不确定这是否适合这种情况。首先更改文本,然后异步加载项目。这正是选择第一个项目的时间。我不确定我是否正确理解了您,但在我看来,这与 Text_Changed 事件本身无关。它用第一个加载条目的文本覆盖用户输入的文本。
-
捕获用户输入的文本,加载项目,恢复文本。 f 您通过更改文本触发加载项目,然后在恢复文本之前设置 ignoreTextChanged=true (如果恢复 txt 再次触发搜索)。您可能还想捕获插入符号的位置,以便您也可以恢复它.. 过去我用两个控件(例如一个文本框和一个列表框)完成了这项工作,这样它们就不会互相争斗