winforms 用于更新datagridview的C#计时器事件

brtdzjyr  于 2022-11-17  发布在  C#
关注(0)|答案(2)|浏览(202)

我正在尝试创建一个带有文本框和datagridview的“dashboard”表单。加载到其中的数据来自每10分钟更新一次的excel电子表格。我添加了一个计时器来刷新数据,但无法更新表单上的文本框和datagridview。我可以告诉计时器正在工作,因为如果我向下滚动到datagridview的底部,表单将更新。我错过了什么?

public AllOrders()
    {
        InitializeComponent();
        System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
        timer1.Interval = 10000;
        timer1.Tick += new System.EventHandler(timer1_Tick);
        timer1.Enabled = true;
        timer1.Start();
        Get_Data();
    }
    private void Get_Data()
    {
        // connect to get file
        string ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='\\\\xxxxx\\labdash.xls';Extended Properties=\"Excel 8.0;HDR=Yes\";";
        OleDbConnection MyConnection = new OleDbConnection(ConnectionString);
        // select only worksheet in spreadsheet
        OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("select * from [Sheet1$]", MyConnection);
        // define dataset as entire spreadsheet
        DataSet ds = new DataSet();
        myDataAdapter.Fill(ds);
        // define view to set filters, restrictions, etc
        DataView dv;
        dv = new DataView(ds.Tables[0], "ordept = 'CHE'", "ordept", DataViewRowState.CurrentRows);
        dataGridView1.DataSource = dv;
        // define header information
        ctr = dataGridView1.Rows.Count;
        textBox1.Text = ctr.ToString() + "  outstanding tests";
        upddte = dataGridView1.Rows[1].Cells[14].Value.ToString();
        updtim = dataGridView1.Rows[1].Cells[15].Value.ToString();
        textBox2.Text = upddte.Substring(5, 2) + "  last updated";
        // hide columns not needed
        dataGridView1.Columns[0].Visible = false;
        dataGridView1.Columns[4].Visible = false;
        dataGridView1.Columns[5].Visible = false;
        dataGridView1.Columns[6].Visible = false;
        dataGridView1.Columns[9].Visible = false;
        dataGridView1.Columns[10].Visible = false;
        dataGridView1.Columns[11].Visible = false;
        dataGridView1.Columns[14].Visible = false;
        dataGridView1.Columns[15].Visible = false;
        dataGridView1.Columns[17].Visible = false;
        // sort by priority, specimen date, specimen time
        dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Ascending);
        dataGridView1.Sort(dataGridView1.Columns[13], ListSortDirection.Ascending);
        dataGridView1.Sort(dataGridView1.Columns[14], ListSortDirection.Ascending);
        // change font color for certain status'
        dataGridView1.RowPrePaint
            += new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(dataGridView1_RowPrePaint);
        dataGridView1.Update();
        dataGridView1.Refresh();
        textBox1.Update();
        textBox1.Refresh();
        textBox2.Update();
        textBox2.Refresh();
    }
    private void timer1_Tick(object sender, EventArgs e)
    {
        Get_Data();
    }
lyfkaqu1

lyfkaqu11#

显然,您的表单类被命名为AllOrders。构造函数:

public AllOrders()
{
    InitializeComponent();
    System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
    ...
}

构造函数末尾的timer1会发生什么?是否有人持有对timer对象的引用?垃圾收集器会做什么?
您的计时器是一个组件。您的窗体可以包含许多组件,但您必须使它们保持活动状态,直到您确定不再需要它们为止。计时器也是IDisposable,您应该在释放窗体时释放它。
对于任何组件来说,最简单的方法就是将组件添加到Form.Components中。请参见窗体的InitializeComponent上面的窗体Dispose代码。
您可以使用Visual Studio设计工具加入计时器。它位于[组件]底下的[工具箱]中。如果您想要手动加入它,请确定它在建构函式之后仍保持作用中,并将它加入this.Components,这样您就知道当处置表单时,它也会被处置。

class Allorders : Form
{
    private readonly Timer timer1;

    public AllOrders()
    {
        InitializeComponent();
        this.timer1 = new Timer();
        this.components.Add(this.timer1);
        ... // other timer initializations
    }
}

Dispose this.components的程式码已经在您的表单中。Dispose this.components会根据您新增到表单的其他控件而定,为null。在这种情况下,您必须自行建立它:

InitializeComponent();

if (this.components == null)
    this.components = new System.ComponentModel.Container();
this.timer1 = new Timer();
this.components.Add(this.timer1);
30byixjq

30byixjq2#

你在计时器的每一个刻度上都添加了一个绘制事件。这会调用多个绘制事件,并使一切变慢,特别是当你在滚动的时候。
将绘制订阅移到构造函数中。另外,在窗体级别声明计时器,以便在窗体关闭时可以正确地释放它。

System.Windows.Forms.Timer timer1;

public AllOrders()
{
  InitializeComponent();
  dataGridView1.RowPrePaint += dataGridView1_RowPrePaint;

  timer1 = new System.Windows.Forms.Timer();
  timer1.Interval = 10000;
  timer1.Tick += timer1_Tick;
  timer1.Start();
}

相关问题