Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reload data in UITableView in MonoTouch?

In my application I display data from a online web service into several UITableViews. I have added several ways for the user to update the data, but the TableView.ReloadData() method does not seem to work. When the user calls for an update, I get a new set of data from the server, pass it to the UITableViewSource instance that is attached to the UITableViewController and then call the ReloadData() method, which unfortunately does not in fact reload the data. Only after I return to the main screen and then go back to the table view (because it is already created, I just display the instance that already exists) does the new data show up in the tableview. What am I doing wrong? I tried creating a new instance of the UITableViewSource when updating the data, but that does not help either.

Here is the code for loading data into the tableview (I reuse it for any event that requires data to be loaded into it):

 dataControl.GetList(Tables.UPDATES)); //gets data from the server and passes it to the SQL database
 Source source = GetSource(theType.Name, theType, groups); //creates a new source loaded with the data
 Updates.TableView.Source = source;
 Updates.TableView.AllowsSelection = false;     
 Updates.TableView.ReloadData();

This code is of course executed in a separate thread that invokes on the main thread. Basically the same code is called when the user asks for an update(an animation is played while the background thread works).

like image 370
Kiril Avatar asked Feb 28 '11 23:02

Kiril


3 Answers

Pavel is correct - try the following to see if it works:

InvokeOnMainThread(delegate{
    Updates.TableView.Source = source;
    Updates.TableView.AllowsSelection = false;
    Updates.TableView.ReloadData();
});

In future, whenever you're dealing with something that will change the UI currently shown, you will need to ensure that it takes place on the main thread (also known as the GUI thread). This InvokeOnMainThread is a method from NSObject so can be called like above in all UIViews / UIViewControllers etc - you can also call it from an entirely C# class using:

MonoTouch.UIKit.UIApplication.SharedApplication.InvokeOnMainThread(delegate{ /*code here*/ });
like image 75
Luke Avatar answered Oct 23 '22 00:10

Luke


You say it is done in a different thread, could it be that the worker thread cannot call the UI thread? I.e. you should call the ReloadData via delegate to be sure it gets called in the UI thread and not "only" in the worker thread, as it might interlock and never get actually called (happened to me in a different scenario).

like image 25
Pavel Sich Avatar answered Oct 22 '22 22:10

Pavel Sich


I also ran into this problem and found this question. Using some of the hint here, I finally got it work by reseting the DataSource and call ReloadView().

tableView.DataSource = new MyDataSource(...);
tableView.RelaodData();

From my testing, it doesn't make different if I wrap the ReloadView() within the InvokeOnMainThread or not. Well, that's maybe because I'm not using worker thread.

It is strange that in another case I could refresh the table view by simply calling ReloadData() in ViewDidAppear(). The only difference is that the above case is the refresh within the same view.

like image 28
newman Avatar answered Oct 23 '22 00:10

newman