2

in my case i wanted to display items from local SQLite database which i created as shown below:

public string CreateDB() //create database
    {
        var output = "";
        string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "IsoModule.db3");
        output = "Database Created";
        return output;
    }

    public string CreateTable() //create table
    {
        try
        {
            string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "IsoModule.db3");
            var db = new SQLiteConnection(dbPath);
            db.CreateTable<UserInfo>();
            db.CreateTable<TableInfo>();
            string result = "Table(s) created";
            return result;
        }
        catch (Exception ex)
        {
            return ("Error" + ex.Message);
        }
    }

and this is my code where i wish to retrieve data

string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "IsoModule.db3");
        var tablelistout = new SQLiteConnection(path);
        var alltables = tablelistout.Table<TableInfo>();
        foreach (var listing in alltables)
        {
            var from = new string[]
            {
                listing.tname + "   -   " + listing.status 
            };

            ListView listtable = (ListView)FindViewById(Resource.Id.listtable);
            listtable.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, from);
            }

the code runs with NO ERROR but it only display last item in the table. it is confusing me, so i would like to ask how can i retrieve all the data from specific table? or if someone has asked the same question please share me the link. many appreciate.

1 Answer 1

2
var alltables = tablelistout.Table<TableInfo>();
var data = new List<string>();
foreach (var listing in alltables)
{
     data.Add(listing.tname + "   -   " + listing.status);
}

ListView listtable = (ListView)FindViewById(Resource.Id.listtable);
listtable.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, data.ToArray());

All I did was move 2 things out of the loop. First, I moved out the initialization of the array. Second, I moved out the listView + assignation of the adapter.

Your issue is that in the loop, you were always overriding everything you had done in the previous iteration (leaving you with the last item like you said).

Also, You should take note that it will be important for you to create a custom adapter if you plan on having a decent amount of data. ArrayAdapter is a native Android class which is then wrapped by a C# Xamarin object, meaning you will have both a C# and Java object per row. It adds overhead as both garbage collectors will have work to do and can cause performance issues. Xamarin devs tend to generally avoid it with the exception of quick prototyping.

On another note, I would use the FindViewById<T>(Int32) instead of the FindViewById(Int32) and casting it. FindViewById<ListView>(Resource.Id.listtable) in your case. Just taking advantage of the power of generics.

Sign up to request clarification or add additional context in comments.

6 Comments

thank you so much, your answer save my life! i will note down your suggestions, thanks again
You should take note that it will be important for you to create a custom adapter if you plan on having a decent amount of data. not really, SimpleCursorAdapter is quite enough, no need to reinvent the wheel
@pskink Actually, SimpleCursorAdapter is a Android sdk adapter that inherits from java.lang.Object and your data will be java objects wrapping your C# data. You will run into similar issues I've described in the answer. You will have the overhead of 2 garbage collectors and you are using double the memory to represent each row. Also, the GCs need to be in "synch" meaning it will generally take more than one pass causing objects to persist in memory longer than they should.
ok i will not pretend that i am xamarin expert, so in your opinion what is described here is not true?
It's a good question, It really depends on what happens behind the scenes. From what I see, you MAY not have the issue with the CursorAdapter on the basis that only the adapter is wrapped in C# and that the adapter creates it's java objects directly from the database without creating any C# counterparts. My explanation comes straight out of the material from the certification. In the case of ArrayAdapter, you definitely do have the problem I'm describing because it needs to wrap the C# objects back to the java world.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.