This is a migrated thread and some comments may be shown as answers.

when ReBind() is called twice, NeedDataSource is not fired the second time

3 Answers 487 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Donald
Top achievements
Rank 1
Donald asked on 15 Feb 2012, 07:07 AM
Hi,

please see this example: when the DoSomething button is pressed, ReBind() is called twice. The second time, the RadGrid does not refresh.

public partial class _default : System.Web.UI.Page
{
  protected override void OnInit(EventArgs e)
  {
    if (!IsPostBack)
    {
      Session["data"] = new List<string>() { "ready", "ready" };
    }
    base.OnInit(e);
  }
 
  protected DataTable GetGridDataTable()
  {
    List<string> data = Session["data"] as List<string>;
     
    DataTable dataTable = new DataTable();
    dataTable.Columns.Add("Name");
 
    foreach (string s in data)
    {
      dataTable.Rows.Add(s);
    }
    return dataTable;
  }
 
  protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
  {
    RadGrid1.DataSource = GetGridDataTable();
  }
 
  protected void Button_Click(object sender, EventArgs e)
  {
    Session["data"] = new List<string>() { "loading", "loading" };
    RadGrid1.Rebind();
    System.Threading.Thread.Sleep(2000);
    Session["data"] = new List<string>() { "finished", "finished" };
    RadGrid1.Rebind();
  }
}
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <div>
        <telerik:RadGrid ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource" Width="400px">
            <MasterTableView DataKeyNames="Name" Name="ParentTable">
                <Columns>
                    <telerik:GridBoundColumn DataField="Name" UniqueName="Name">
                    </telerik:GridBoundColumn>
                </Columns>
            </MasterTableView>
        </telerik:RadGrid>
        <asp:Button Text="Do something" OnClick="Button_Click" runat="server"/>
    </div>
    </form>
</body>
</html>

Right now, after the button is pressed, the grid displays "loading", but then does not display "finished". How would I get RadGrid to correctly display "loading" and then "finished"?
Thanks,
Donald

3 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 15 Feb 2012, 03:35 PM
Hello,

Calling Rebind operation of RadGrid does not mean that the Grid will fire its NeedDataSource event. RadGrid decides when it does need to fire the event. You could try to assign null to RadGrid datasource and then call Rebind, thus the NeedDataSource event should be fired.

protected void Button_Click(object sender, EventArgs e)
{
  Session["data"] = new List<string>() { "loading", "loading" };
  RadGrid1.Rebind();
  System.Threading.Thread.Sleep(2000);
  Session["data"] = new List<string>() { "finished", "finished" };
  RadGrid1.DataSource=null;
  RadGrid1.Rebind();
}


Give this suggestion a try and check whether you get the expected behavior.

Kind regards,
Andrey
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Donald
Top achievements
Rank 1
answered on 16 Feb 2012, 01:47 AM
Hi, Andrey,

Your solution worked in my above example, but I am actually using a delegate to invoke a calculation method (that takes some time to run) asynchronously. The method completed event handler is HandleRequestCompleted(). In HandleRequestCompleted(), NeedDataSource is not called when I call ReBind(), even after setting DataSource = null.

Right before the calculation method (which takes some time to run), HandleBeforeRequest is fired, and the grid displays "loading" correctly. After the calculation finishes, HandleRequestCompleted is fired but the grid does not update to display "finished".

public partial class _default : System.Web.UI.Page, ICalculatorDelegate
{
  protected override void OnInit(EventArgs e)
  {
    if (!IsPostBack)
    {
      Session["data"] = new List<string>() { "test1", "test2" };
    }
    base.OnInit(e);
  }
 
  protected DataTable GetGridDataTable()
  {
    List<string> data = Session["data"] as List<string>;
     
    DataTable dataTable = new DataTable();
    dataTable.Columns.Add("Name");
 
    foreach (string s in data)
    {
      dataTable.Rows.Add(s);
    }
    return dataTable;
  }
 
  protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
  {
    RadGrid1.DataSource = GetGridDataTable();
  }
 
  protected void Button_Click(object sender, EventArgs e)
  {
    new Calculator() { Delegate = this }.Run();
  }
 
  public void HandleBeforeRequest()
  {
    Session["data"] = new List<string>() { "loading", "loading" };
    RadGrid1.Rebind();
  }
 
  public void HandleRequestCompleted()
  {
    Session["data"] = new List<string>() { "finished", "finished" };
    RadGrid1.DataSource = null;
    RadGrid1.Rebind();
  }
}
 
 
public interface ICalculatorDelegate
{
  /// <summary>
  /// Invoked before the request has started.
  /// </summary>
  ///
  void HandleBeforeRequest();
 
  /// <summary>
  /// Invoked when the request has successfully completed.
  /// </summary>
  void HandleRequestCompleted();
};
 
 
public class Calculator
{
  public ICalculatorDelegate Delegate;
 
  public Calculator()
  {
  }
 
  public void Run()
  {
    new Thread
    (delegate()
      {
        if (this.Delegate != null)
        {
          this.Delegate.HandleBeforeRequest();
        }
        this.InvokeRequests();
 
        if (this.Delegate != null)
        {
          this.Delegate.HandleRequestCompleted();
        }
      }).Start();
  }
 
  protected void InvokeRequests()
  {
    Thread.Sleep(2000);
  }
 
}
Please help with this unexpected behaviour,
Donald
0
Accepted
Andrey
Telerik team
answered on 20 Feb 2012, 03:00 PM
Hi,

I reviewed your latest code and noticed that you are executing the Run method of the Calculator class in a different thread. Using multi-thread logic in ASP.NET is not a suggested approach. The synchronization between the threads and their resources won't be an easy task. In your case the problem might came from that the RadGrid is using one thread but the datasource is in another thread. This approach is typical for a Silverlight project not for ASP.NET.

Additionally, if you want to show to the user that some process is working on the server the better approach is to use RadAjaxLoadingPanel. And if you need to do something asynchronously in ASP.NET you need to use Ajax.  This is true because using Ajax you are requesting a new page from the server with partially updated content instead of an asynchronous call to the server which will update only the datasource. You could check this MSDN thread for more information on the ASP.NET architecture.

Basically, your case could be achieved by Ajax-ifying the grid instance on button click. While the request to the server is made the user will see Loading panel which will inform the user that the control will be updated soon with new content. You could check this help topic for more information on how to Ajax-ify controls with RadAjaxManager and here how to use RadAjaxLoadingPanel.

Give these suggestion a try and I think you will manage to run the code without a problem.

Greetings,
Andrey
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Tags
Grid
Asked by
Donald
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Donald
Top achievements
Rank 1
Share this question
or