Search code examples
c#xamarin.android

Xamarin Android with Mysql DataAdapter gives an Array Error System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'


I have a Xamarin Android project where I want to output database tables using ListView and mysql.

The connection to the database works, but as soon as the array passes the data to ListView Adapter, I get the error: System.IndexOutOfRangeException: 'Index was outside the bounds of the array'.

The database has 8 rows (id,itemName,itemPrice,itemsBought,usedGold,user,seller,timestamp)

Thats my activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
</RelativeLayout>

Thats my Constants.cs (xxx as placeholders):

namespace NTA_Mobile
{
    public static class Constants
    {
        #region Fields

        public static string connectionString = ("server=xxx;user id=xxx;password=xxx;persistsecurityinfo=True;database=xxx;");

        public static string selectAllQueryHistory = "select * from boughtitemhistory order by id desc";

        #endregion Fields
    }
}

And here's my MainActivity.cs:

using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Widget;
using AndroidX.AppCompat.App;
using MySqlConnector;
using System.Collections;

namespace NTA_Mobile
{
    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {
        #region Fields

        private ArrayList data = new ArrayList();
        private ListView listView1;

        #endregion Fields

        #region Public Methods

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

        #endregion Public Methods

        #region Protected Methods

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            listView1 = FindViewById<ListView>(Resource.Id.listView1);
            LoadData();
        }

        #endregion Protected Methods

        #region Private Methods

        private async void LoadData()
        {
            MySqlConnection conn = new MySqlConnection(Constants.connectionString);
            await conn.OpenAsync();

            MySqlCommand cmd = new MySqlCommand(Constants.selectAllQueryHistory, conn);
            cmd.Connection = conn;

            MySqlDataReader rdr = cmd.ExecuteReader();
            if (rdr.HasRows)
            {
                while (rdr.Read())
                {
                    data.Add(rdr[1]);
                }
                rdr.Close();

                listView1.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, data);
            }
        }

        #endregion Private Methods
    }
}

I tried to use string[] as in the Microsoft documentation, but it doesn't work either. I tried with just one row because i though it would be easier, but in the end it should display all rows.


Solution

  • In my case I used the MySqlConnector from Bradley Grainger installed via Nuget and I had to change

    private async void LoadData()
        {
            MySqlConnection conn = new MySqlConnection(Constants.connectionString);
            await conn.OpenAsync();
    

    to

    private void LoadData()
        {
            MySqlConnection conn = new MySqlConnection(Constants.connectionString);
            conn.Open();
    

    Now it works like intended.