Search code examples
xamarindata-bindingandroid-sqlitepicker

Display Table info when picker item is selected


I am still a beginner so bear with me.

I am trying to change the displayed information (in an ActionSheet and on other pages) based on the selectedItem of a picker. Each item in the picker refers to a column on a table, and has its own row Id (set to autoIncrement). I am able to save (and display as needed) the current SelectedItem, but only as that items name, and nothing else associated with that row (that I am aware of).

I should be able to use the binding properties of the picker to do this, but it doesn't want to work. I feel I am missing something stupid.

Xaml.cs

using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
            {

                var terms = conn.Table<Terms>().ToList().FirstOrDefault();//Lets me access the columns on the table

                var pickerItem = termPicker.Items[termPicker.SelectedIndex]; //Lets me save and use the TermName

                DisplayActionSheet(PickerItem.TermName, "Ok", null, "Term Status: " + PickerItem.TermStatus,
               "Projected Start: " + PickerItem.TProjStart.ToString(),
               "Projected End: " + PickerItem.TProjEnd.ToString(),
               "Actual Start: " + PickerItem.TActStart.ToString(),
               "Actual End : " + PickerItem.TActEnd.ToString()); ;


            }

Xaml

<Picker x:Name="termPicker"
                    ItemsSource="{Binding Terms}"
                    ItemDisplayBinding="{Binding TermName}"
                    Title="Select a term"
                    IsEnabled="True"
                    SelectedItem="{Binding PickerItem}"/>

Table

 public class Terms
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string TermName { get; set; } 
        public string TermStatus { get; set; } 
        public DateTime TProjStart { get; set; }
        public DateTime TProjEnd { get; set; } 
        public DateTime TActStart { get; set; } 
        public DateTime TActEnd { get; set; } 
        public Object PickerItem { get; set; } 

If I use term.TermName etc. in the DisplayActionSheet, it works(ish) but only will display what the default values are, regardless of the Picker SelectedItem. If I change the DisplayActionSheet to PickerItem.TermName etc., it gives the error "object does not contain a definition for TermName".

I understand that SelectedItem is an object, but I'm not sure how to set that object to reference the Terms table, or the row that the SelectedItem is tied to.

Any help would be greatly appreciated. Thanks!

Edit: Adding most current and working code:

 public class Terms
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string TermName { get; set; } 
        public string TermStatus { get; set; } 
        public DateTime TProjStart { get; set; }
        public DateTime TProjEnd { get; set; } 
        public DateTime TActStart { get; set; } 
        public DateTime TActEnd { get; set; } 

OnAppearing

 protected override void OnAppearing()
        {
            base.OnAppearing();

            using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
            {
                conn.CreateTable<Terms>();
                conn.CreateTable<Courses>();
                conn.CreateTable<Assessments>();

                var terms = conn.Table<Terms>().ToList();
                var courses = conn.Table<Courses>().ToList();
                var assessments = conn.Table<Assessments>().ToList();

                termPicker.ItemsSource = terms;


                var dateNow = DateTime.Now;
                if (!terms.Any())
                {
                    conn.Insert(new Terms
                    {
                        TermName = "Demo Term",
                        TermStatus = "In Progress",
                        TProjStart = dateNow,
                        TProjEnd = dateNow,
                        TActStart = dateNow,
                        TActEnd = dateNow
                    });
                }

Event Handler

            void InfoClicked(Object sender, EventArgs e)

            {
                using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
                {

                    var terms = conn.Table<Terms>().ToList().FirstOrDefault();

                    var pickerItem = termPicker.Items[termPicker.SelectedIndex];

                    DisplayActionSheet(pickerItem, "Ok", null, "Term Status: " + terms.TermStatus,
                    "Projected Start: " + terms.TProjStart.ToString(),
                    "Projected End: " + terms.TProjEnd.ToString(),
                    "Actual Start: " + terms.TActStart.ToString(),
                    "Actual End : " + terms.TActEnd.ToString());


                }

            }

Picker Bindings

        <StackLayout>

            <Picker x:Name="termPicker"
                    ItemsSource="{Binding Terms}"
                    ItemDisplayBinding="{Binding TermName}"
                    Title="Select a term"
                    IsEnabled="True"
                    SelectedItem="{Binding pickerItem}"/>


Solution

  • a Picker has a SelectedItem property on it, all you need to do is cast it to the correct type. Then you can access all of the individual properties on term

    void InfoClicked(Object sender, EventArgs e)
    {
      var term = (Terms)termPicker.SelectedItem;
    
      DisplayActionSheet(term.TermName, "Ok", null, "Term Status: " +  term.TermStatus,
                    "Projected Start: " + term.TProjStart.ToString(),
                    "Projected End: " + term.TProjEnd.ToString(),
                    "Actual Start: " + term.TActStart.ToString(),
                    "Actual End : " + term.TActEnd.ToString());
    
    }