winforms 如何使用textbox textChanged属性和后台工作进程填充datagridview

kg7wmglp  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(136)

在我的表单中,我有一个文本框、后台工作器和一个数据网格视图。2使用文本框(TextChanged属性),我想使用后台工作器填充数据,并在数据网格视图中填充匹配的数据。
这是我试过的。
第一个
这个后台工作线程当前正忙,没有同时运行多个任务。
我该怎么办?

polkgigr

polkgigr1#

如果您愿意接受比使用BackgroundWorker更简单的方法,我建议您为textbox.TextChanged事件创建一个async处理程序,记录在等待快速输入的“冷却”期之前的击键计数。如果计数在等待此延迟之前和之后相同,则表明输入足够稳定,可以执行查询。

为了方便起见,我用sqlite-net-pcl模拟了这个过程。DGV绑定到一个DataSource,它是一个BindingList<Game>OnLoad覆盖MainForm初始化DataGridView,然后初始化你正在使用的任何数据库服务器。最后一件事是订阅TextChanged事件,这是所有动作发生的地方。

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    initDGV();
    initSQL();
    textBox.TextChanged += onTextBoxTextChanged;
}
BindingList<Game> DataSource = new BindingList<Game>();
// Comparing the awaited count to the total count so that
// the DGV isn't visually updated until all queries have run.
int _queryCount = 0;

TextBox.TextChanged事件处理程序(异步)

private async void onTextBoxTextChanged(object sender, EventArgs e)
{
    if(string.IsNullOrWhiteSpace(textBox.Text))
    {
        return;
    }
    _queryCount++;
    var queryCountB4 = _queryCount;
    List<Game> recordset = null;
    var captureText = textBox.Text;

    // Settling time for rapid typing to cease.
    await Task.Delay(TimeSpan.FromMilliseconds(250));

    // If keypresses occur in rapid succession, only
    // respond to the latest one after a settling timeout.
    if (_queryCount.Equals(queryCountB4))
    {
        await Task.Run(() =>
        {
            using (var cnx = new SQLiteConnection(ConnectionString))
            {
                var sql = $"SELECT * FROM games WHERE GameID LIKE '{captureText}%'";
                recordset = cnx.Query<Game>(sql);
            }
        });
        DataSource.Clear();
        foreach (var game in recordset)
        {
            DataSource.Add(game);
        }
    }
    else Debug.WriteLine("Waiting for all pending queries to complete");
}

数据网格视图

private void initDGV()
{
    dataGridView.DataSource = DataSource;
    dataGridView.AllowUserToAddRows = false;
    DataSource.Add(new Game { GameID = "Generate Columns" });
    dataGridView
        .Columns[nameof(Game.GameID)]
        .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    dataGridView
        .Columns[nameof(Game.Created)]
        .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    DataSource.Clear();
}

数据库

private void initSQL()
{
    // For testing, start from scratch every time
    if (File.Exists(ConnectionString)) File.Delete(ConnectionString);
    using (var cnx = new SQLiteConnection(ConnectionString))
    {
        cnx.CreateTable<Game>();
        cnx.Insert(new Game { GameID = "Awe" });
        cnx.Insert(new Game { GameID = "Abilities" });
        cnx.Insert(new Game { GameID = "Abscond" });
        cnx.Insert(new Game { GameID = "Absolve" });
        cnx.Insert(new Game { GameID = "Absolute" });
    }
}

游戏

[Table("games")]
class Game
{
    [PrimaryKey, Browsable(false)]
    public string Guid { get; set; } = System.Guid.NewGuid().ToString().ToUpper();
    public string GameID { get; set; }
    private DateTime _created = DateTime.Now.Date;
    public string Created 
    {
        get => _created.ToShortDateString();
        set
        {
            if(DateTime.TryParse(value, out DateTime dt))
            {
                _created = dt.Date;
            }
        }
    }
}

相关问题