首页 > 解决方案 > 带有用户名数据的 AutoCompleteCustomSource 不起作用

问题描述

我正在尝试创建一个具有自动完成功能的文本框。
在我的表单的构造函数中,我从数据库中获取数据并将 TextBoxAutoCompleteCustomSource属性设置为用户名数组。
由于某种原因,自动完成功能无法正常工作。

我确信该db.getUsersList()方法没有问题(底部的屏幕截图)。

public mainPanel()
{
    InitializeComponent();
    AutoCompleteStringCollection collection = new AutoCompleteStringCollection();
    collection.AddRange(db.getUserList().ToArray());
    nickName.AutoCompleteCustomSource = collection;
}

在此处输入图像描述

标签: c#winformsautocompletetextbox

解决方案


要设置支持自动完成的控件,必须指定自动完成功能的来源。当使用AutoCompleteCustomSource属性设置为字符串集合时, AutoCompleteSource属性必须设置为AutoCompleteSource.CustomSource并且AutoCompleteMode设置为AutoCompleteMode.SuggestAppendAutoCompleteMode.Suggest

这些属性必须一起使用来指定自动完成功能的工作方式。

由于看起来问题中的代码正在使用某种数据源来创建集合,因此这里有一个通用示例,它从 aAutoCompleteCustomSource创建 a ,使用类将绑定添加到控件并使用 a更新某些控件的值。 CustomSourceList<class>BindingBindingSource

该示例使用三个控件:一个 TextBox ( txtAutoComp),其中启用了 AutoComplete 功能,以及两个标签 (lblNickNamelblNickValue),绑定到同一个数据源,当 AutoComplete 控件的文本更改时更新。
AutoComplete 被扩展以允许使用部分字符串查找元素,或者单击按钮(btnFindNick,此处)或按下EnterTextBox 中的键:

文本框自动完成自定义源

private class NickName
{
    public string Nick { get; set; }
    public int Value { get; set; }
}

private BindingSource source = null;
private List<NickName> NickNames = null;

private void Form1_Load(object sender, EventArgs e)
{
    NickNames = new List<NickName>();
    NickNames.AddRange(new[] {
        new NickName() { Nick = "", Value = 0 },
        new NickName() { Nick = "Andrea", Value = 10 },
        new NickName() { Nick = "Arnold", Value = 20 },
        new NickName() { Nick = "Barbara", Value = 30 },
        new NickName() { Nick = "Billy", Value = 40 },
        new NickName() { Nick = "Clint", Value = 50 },
        new NickName() { Nick = "Cindy", Value = 60 },
    });
    source = new BindingSource();
    source.DataSource = NickNames;

    txtAutoComp.AutoCompleteMode = AutoCompleteMode.Suggest;
    txtAutoComp.AutoCompleteSource = AutoCompleteSource.CustomSource;
    txtAutoComp.AutoCompleteCustomSource.AddRange(NickNames.Select(n => n.Nick).ToArray());

    Binding textBind = new Binding("Text", source, "Nick", true, DataSourceUpdateMode.OnPropertyChanged);
    textBind.Parse += (s, evt) => {
        source.CurrencyManager.Position = NickNames.FindIndex(1, r => r.Nick.Equals(evt.Value));
    };

    txtAutoComp.DataBindings.Add(textBind);
    lblNickName.DataBindings.Add(new Binding("Text", source, "Nick"));
    lblNickValue.DataBindings.Add(new Binding("Text", source, "Value"));
}

private void btnFindNick_Click(object sender, EventArgs e)
{
    FindNick(txtAutoComp.Text);
}

private void txtAutoComp_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter) {
        e.SuppressKeyPress = true;
        FindNick(txtAutoComp.Text);
    }
}

void FindNick(string partialName) 
    => this.source.CurrencyManager.Position = NickNames.FindIndex(
        1, r => r.Nick.Contains(partialName)
    );

推荐阅读