Katherine Williams
Katherine Williams

Reputation: 732

ASP.NET - Make gridview (DataTable source) refresh after new row is added (triggered by timer)

I have a method that is triggered every minute by a timer, and this method adds a row to a DataTable. There is a GridView on the page which has this DataTable as its course. Every time a row is added, I DataBind() - the new row shows up in the DataTable (I can see it in the debugger), but not on the GridView.

I won't overwhelm you with code, but I'll try to show everything relevant.

Here are the declarations for the timer and the DataTable source:

static DataTable logTable;
System.Timers.Timer timeoutTimer;

Here's what happens on Page_Load:

   protected void Page_Load(object sender, System.EventArgs e)
    {
        if (logTable == null)
        {
            logTable = new DataTable();
            logTable.Columns.Add(new DataColumn("Timestamp", typeof(string)));
            logTable.Columns.Add(new DataColumn("Type", typeof(string)));
            logTable.Columns.Add(new DataColumn("Message", typeof(string)));
        }
    }

Here's how the timer gets initialized (it DOES fire successfully every minute):

    StopTime = DateTime.Now.AddMinutes(5);

    timeoutTimer = new System.Timers.Timer(60000);
    timeoutTimer.Interval = 60000;
    timeoutTimer.Elapsed += new ElapsedEventHandler(RunningStatusesTick);
    timeoutTimer.Start();

    GC.KeepAlive(timeoutTimer);

Here's the tick method:

    private void RunningStatusesTick(object sender, ElapsedEventArgs e){

        try
        {
            string info = GetRawInfo();
            recordResults(info);

        }
        catch (Exception ex)
        {
            // Error thrown?  Catch it and record it.
            recordResults(ex.Message, true);
        }
    }

Here's the method that adds new rows to the DataTable (and does the DataBind()):

    private void recordResults(string ResultText, bool IsError = false)
    {
        DataRow logRow = logTable.NewRow();
        logRow["Timestamp"] = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();
        logRow["Type"] = (IsError ? "ERROR" : "INFO");
        logRow["Message"] = ResultText;
        logTable.Rows.Add(logRow);

        gvLogTable.DataSource = null;
        gvLogTable.DataSource = logTable;
        gvLogTable.DataBind();
    }

And finally, here are the aspx tags with the gridview:

<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView runat="server" id="gvLogTable"></asp:GridView>
    </div>
    </form>
</body>
</html>

Things I've already tried:

Thanks so much in advance! :)

Upvotes: 2

Views: 6978

Answers (1)

Jon Senchyna
Jon Senchyna

Reputation: 8037

It looks to me like your rebind is incorrect. In the recordResults() function, your last three lines are as follows:

gvLogTable.DataSource = null;
gvLogTable.DataSource = logRow;
gvLogTable.DataBind(); 

I think you want to be binding to logTable, not logRow.

Alternately, have you tried using BindingListCollectionView and the associated Refresh() method? I'm not sure if it will solve your problems, but it might be worth a look.

Upvotes: 1

Related Questions