Forum Xamarin.Forms

how can we achieve that :-sublist in parents listview but in taaped next page.

shiwamshiwam Member ✭✭
edited February 2020 in Xamarin.Forms
in parents listview. When we tap an item then open a second page with the children listview that belongs to parents .

Best Answer

  • shiwamshiwam Member ✭✭
    Accepted Answer

    //////////////////////////////Model/////////////////////////////////////
    public class ClassInfos
    {
    [PrimaryKey, AutoIncrement]
    public int ClassId { get; set; }
    public string ClassName { get; set; }

    }
    

    public class StudentInfo
    {
    [PrimaryKey, AutoIncrement]
    public int StudentId { get; set; }
    public int Classid { get; set; }
    public string studentName { get; set; }

    }
    

    /////////////////////////first page////////////////////////////////////////////////////////////
    public SQLiteConnection conn;
    public MainPage()
    {
    InitializeComponent();
    using (conn = new SQLiteConnection(App.Database))
    {
    conn.CreateTable();
    var data = conn.Table().OrderBy(c => c.ClassId).ToList();

                Datalist.ItemsSource = data;
            }
        }
    
        public void AddButton_Clicked(object sender, EventArgs e)
        {
            if (ClassEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
            }
            else
            {
                using (conn = new SQLiteConnection(App.Database))
                {
                    conn.CreateTable<ClassInfos>();
                    ClassInfos classinfo = new ClassInfos
                    {
                        ClassName = ClassEntry.Text
                    };
    
                    conn.Insert(classinfo);
                    DisplayAlert(classinfo.ClassName, "Saved", "Ok");
                    Navigation.PopToRootAsync();
                    ClassEntry.Text = "";
                }
            }
    
        }
    

    ///////////////////////////////////Second Page///////////////////
    SQLiteConnection conn;
    ClassInfos Info;
    public StudentList(ClassInfos Infos)
    {
    InitializeComponent();
    this.Info = Infos;
    }

        private void AddButton_Clicked(object sender, EventArgs e)
        {
            if (StudentEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
    
            }
            else
            {
                try
                {
                    using (conn = new SQLiteConnection(App.Database))
                    {
                        StudentInfo std = new StudentInfo();
                        std.studentName = StudentEntry.Text;
                        std.Classid = Info.ClassId;///here assigning the parents id to Student TAble
                        conn.CreateTable<StudentInfo>();
                        conn.Insert(std);
                    }
                        StudentEntry.Text = "";
                }
                catch(Exception ex)
                {
                    DisplayAlert("Message", ex.Message, "Ok");
                }
    
            } 
        }
        protected override void OnAppearing()
        {
            base.OnAppearing();
            try
            {
                using (conn = new SQLiteConnection(App.Database))
                {
                    var data = conn.Table<StudentInfo>().Where(c => c.Classid == Info.ClassId);//Getting the child 
                    Studentlist.ItemsSource = data;
                }   
            }
            catch (Exception ex)
            { 
    
                DisplayAlert("Message",ex.Message , "Ok");
            }
    
        }
    }
    

Answers

  • ReedReed Member ✭✭

    When you're clicking the item and navigating to the other page, pass the subcollection as the argument through the constructor of your ViewModel/View, depending on how you do the navigation.

  • shiwamshiwam Member ✭✭
    edited February 2020

    Here my code & i'm doing it by passing parents id to the next page & i am confused with onetomany relationship here ...from this code i can add only one children in respected parents & if i try to add other children then previous one get overwrite bye new One.
    Sir plz help me i am a beginner

    //////////////////////////////Model/////////////////////////////////////

     public class ClassInfos
     {
        [PrimaryKey,AutoIncrement]
        public int ClassId { get; set; }
        public string ClassName { get; set; }
    
        [OneToMany(CascadeOperations = CascadeOperation.All)]
        public List<StudentInfo> Students { get; set; }
     }
    
    public class StudentInfo
    {
        [PrimaryKey, AutoIncrement]
        public int StudentId { get; set; }
    
       [ForeignKey(typeof(ClassInfos))]
        public int Classid { get; set; }
    
       // [ManyToOne]
        // public ClassInfos User { get; set; }
        public string studentName { get; set; }
    
     }
    

    //////////////////////////////////////////////////////////AddClass.cs Page/////////////////////////////////////////////////////////////

        public  void  AddButton_Clicked(object sender, EventArgs e)
        {
            if (ClassEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
            }
            else
            {
                using (conn = new SQLiteConnection(App.Database))
                {
                    ClassInfos classinfo = new ClassInfos();
    
                    classinfo.ClassName = ClassEntry.Text;
                    conn.CreateTable<ClassInfos>();
                    conn.Insert(classinfo);
                    DisplayAlert(classinfo.ClassName, "Saved", "Ok");
                    Navigation.PopToRootAsync();
                    ClassEntry.Text = "";
                }
            }
    
        }
        protected override void OnAppearing()
        {
            base.OnAppearing();
            using (conn = new SQLiteConnection(App.Database))
            {
                conn.CreateTable<ClassInfos>();
                var data = conn.Table<ClassInfos>().OrderBy(c => c.ClassId).ToList();
    
                Datalist.ItemsSource = data;
            }
    
        }
       public void Datalist_ItemTapped(object sender, ItemTappedEventArgs e)
        {
              ClassInfos details = e.Item as ClassInfos;
              Navigation.PushAsync(new StudentList(details.ClassId));
        }
    

    ////////////////////////////////////////////////Studentlist.cs page ///////////////////////////////////////////////////////////

      public SQLiteConnection conn;
    
        readonly private int classId;
       // public ClassInfos clssinfo;
    
    
        public StudentList(int classId)
        {
            InitializeComponent();
           this.classId = classId;
    
        }
    
        private void AddButton_Clicked(object sender, EventArgs e)
        {
            if (StudentEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
    
            }
            else
            {
                conn = new SQLiteConnection(App.Database);
                conn.CreateTable<StudentInfo>();
                StudentInfo studentinfo = new StudentInfo()
                {
                    studentName = StudentEntry.Text,
                };
    
                var data =conn.Table<ClassInfos>();
                int id = Convert.ToInt32(classId);
                var data1 = (from values in data where values.ClassId == id select values).Single();
                data1.Students = new List<StudentInfo>();//  { studentinfo };
                conn.Insert(studentinfo);
                data1.Students.Add(studentinfo);
                conn.UpdateWithChildren(data1);
                //var data2 = conn.GetWithChildren<ClassInfos>(data1.ClassId, recursive: true);
               // conn.GetWithChildren<StudentInfo>(studentinfo.StudentId, recursive: true);
    
                StudentEntry.Text = "";
    
    
            }
    
        }
        protected override void OnAppearing()
        {
            base.OnAppearing();
            conn = new SQLiteConnection(App.Database);
            int id = Convert.ToInt32(classId);
            List<StudentInfo> list = conn.GetAllWithChildren<StudentInfo>().Where(c => c.Classid == id).ToList();
            Studentlist.ItemsSource =list;
    
    
        }
    }
    
  • shiwamshiwam Member ✭✭

    plz help me with small demo

  • ColeXColeX Member, Xamarin Team Xamurai
    edited February 2020

    Pass the list(not classid) to the next page .

    First Page

      public void Datalist_ItemTapped(object sender, ItemTappedEventArgs e)
        {
              ClassInfos details = e.Item as ClassInfos;
              Navigation.PushAsync(new StudentList(details.Students));
        }
    

    Second Page

    public StudentList( List<StudentInfo> stu)
    {
        InitializeComponent();
        this.Stu= stu;
       Studentlist.ItemsSource =stu;
    }
    
  • shiwamshiwam Member ✭✭

    @ColeX said:
    Pass the list(not classid) to the next page .

    First Page

      public void Datalist_ItemTapped(object sender, ItemTappedEventArgs e)
        {
              ClassInfos details = e.Item as ClassInfos;
              Navigation.PushAsync(new StudentList(details.Students));
        }
    

    Second Page

    public StudentList( List<StudentInfo> stu)
    {
        InitializeComponent();
        this.Stu= stu;
       Studentlist.ItemsSource =stu;
    }
    

    sir i have tried but not getting the children .Sir Give me full demonstration of this cause my whole project depend upon this so sir plz.
    Here's my UI & code:-

        SQLiteConnection conn;
        List<StudentInfo> Stu;
        public StudentList(List<StudentInfo> stu)
        {
            InitializeComponent();
            this.Stu = stu;
            Studentlist.ItemsSource =stu;
    
    
        }
        private void AddButton_Clicked(object sender, EventArgs e)
        {
            if (StudentEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
    
            }
            else
            {
                conn = new SQLiteConnection(App.Database);
                conn.CreateTable<StudentInfo>();
                StudentInfo std = new StudentInfo()
                {
                    studentName = StudentEntry.Text,
                };
                conn.Insert(std);
                Stu.Add(std);
                StudentEntry.Text = "";
    
            }
        }
    }
    
  • ColeXColeX Member, Xamarin Team Xamurai

    Add breakpoint on ClassInfos details = e.Item as ClassInfos; in item tap event to see if details null or not.

  • shiwamshiwam Member ✭✭
    edited February 2020
    @ColeX
    everything seems fine up to this .. details is null & while navigating it passing the information to next page but
    in the execution process of
    Stu.Add(std);
    it throw exception Unhandled i.e object is not set to an instance of an object.
  • ColeXColeX Member, Xamarin Team Xamurai

    The problem is the rendering/binding on the First page , not the parameter passed to second page .

  • ColeXColeX Member, Xamarin Team Xamurai
    edited February 2020

    Try to move the code into ItemSelected instead of ItemTapped on ListView.

     <ListView ItemSelected="ListView_ItemSelected"/>
    
       private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            ClassInfos details = e.SelectedItem as ClassInfos;
            Navigation.PushAsync(new StudentList(details.ClassId));
        }
    
  • shiwamshiwam Member ✭✭
    edited February 2020
    @ColeX
    nothing happening ...it doesn't even navigate to next page by ItemSelected method by calling Navigating function ..& i don't know why...
  • shiwamshiwam Member ✭✭
    plz provide me one demo for this from start to end
  • shiwamshiwam Member ✭✭
    edited February 2020
    > @ColeX said:> @ColeX said:
    > Try to move the code into ItemSelected instead of ItemTapped on ListView.
    >
    > <ListView ItemSelected="ListView_ItemSelected"/> private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e) { ClassInfos details = e.SelectedItem as ClassInfos; Navigation.PushAsync(new StudentList(details.ClassId)); }

    Nothing changed still same error i.e
    object is not set to an instance of an object at Stu.Add(std);
  • shiwamshiwam Member ✭✭
    I think no one gonna help me.Thanks to all the seniors developer...
  • ColeXColeX Member, Xamarin Team Xamurai

    Hi if possible could you provide me a basic mini project to test ?

    Just zip the project and attach in the comment .

  • shiwamshiwam Member ✭✭
    edited February 2020

    sir here's zip file the method i tried before i.e passing the id to the next page & bye this method & i can bind the data on First page but only one student i can able to add in respected items.

    According to my thought :-
    ""i even tried your method & the subcollection i.e details.Students passing that as args in next page But if i am only passing the List then how can 2nd page know that this subcollection belong to that respected parents id cause for next page "List Stu" is just as a new List Stu for next page which has no parents detail .... & dont even know that it belongs to ClassInfos Table as Children For that i tried by passing two parameter "details.Students & details.Id" to the next page & assign the list Stu to the table ClassInfo by the help of details.id & assign to that ClassInfos.Students." But it don't work so I came back to my previous code & which i have already attached.

  • shiwamshiwam Member ✭✭

    @ColeX sir help me with this

  • ColeXColeX Member, Xamarin Team Xamurai

    There are some points needs to notice in your sample

    1. Create Table for StudentInfo .

    2. Insert data for StudentInfo table .

    3. Relate StudentInfo with ClassInfos .

    Details check

    https://www.codejourney.net/2017/05/sqlite-net-extensions-one-to-many-relationships/
    https://github.com/jsuarezruiz/Xamarin.Forms-Samples/tree/master/TodoSqlite Multiple Tables

  • shiwamshiwam Member ✭✭
    edited February 2020

    @ColeX said:
    There are some points needs to notice in your sample

    1. Create Table for StudentInfo .

    2. Insert data for StudentInfo table .

    3. Relate StudentInfo with ClassInfos .

    Details check

    https://www.codejourney.net/2017/05/sqlite-net-extensions-one-to-many-relationships/
    https://github.com/jsuarezruiz/Xamarin.Forms-Samples/tree/master/TodoSqlite Multiple Tables

    i did the same things before ..i am already gone through that site...& i am doing the same things but problem is i can only able to add one children ..& when insert next children to the respected parents (suppose now studentid is 1 & name is Stefan & when i insert next student as Ram the studentid=2 & Name is =Ram ..it show up in list view but prevoius name Stefan is gone from listview it only show Ram.)problem is How can i retrive all the student from that respected parents in list view..

  • shiwamshiwam Member ✭✭

    @shiwam said:
    Here my code & i'm doing it by passing parents id to the next page & i am confused with onetomany relationship here ...from this code i can add only one children in respected parents & if i try to add other children then previous one get overwrite bye new One.
    Sir plz help me i am a beginner

    //////////////////////////////Model/////////////////////////////////////

     public class ClassInfos
     {
        [PrimaryKey,AutoIncrement]
        public int ClassId { get; set; }
        public string ClassName { get; set; }
    
        [OneToMany(CascadeOperations = CascadeOperation.All)]
        public List<StudentInfo> Students { get; set; }
     }
    
    public class StudentInfo
    {
        [PrimaryKey, AutoIncrement]
        public int StudentId { get; set; }
    
       [ForeignKey(typeof(ClassInfos))]
        public int Classid { get; set; }
    
       // [ManyToOne]
        // public ClassInfos User { get; set; }
        public string studentName { get; set; }
    
     }
    

    //////////////////////////////////////////////////////////AddClass.cs Page/////////////////////////////////////////////////////////////

        public  void  AddButton_Clicked(object sender, EventArgs e)
        {
            if (ClassEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
            }
            else
            {
                using (conn = new SQLiteConnection(App.Database))
                {
                    ClassInfos classinfo = new ClassInfos();
                    
                    classinfo.ClassName = ClassEntry.Text;
                    conn.CreateTable<ClassInfos>();
                    conn.Insert(classinfo);
                    DisplayAlert(classinfo.ClassName, "Saved", "Ok");
                    Navigation.PopToRootAsync();
                    ClassEntry.Text = "";
                }
            }
    
        }
        protected override void OnAppearing()
        {
            base.OnAppearing();
            using (conn = new SQLiteConnection(App.Database))
            {
                conn.CreateTable<ClassInfos>();
                var data = conn.Table<ClassInfos>().OrderBy(c => c.ClassId).ToList();
                
                Datalist.ItemsSource = data;
            }
              
        }
       public void Datalist_ItemTapped(object sender, ItemTappedEventArgs e)
        {
              ClassInfos details = e.Item as ClassInfos;
              Navigation.PushAsync(new StudentList(details.ClassId));
        }
    

    ////////////////////////////////////////////////Studentlist.cs page ///////////////////////////////////////////////////////////

      public SQLiteConnection conn;
      
        readonly private int classId;
       // public ClassInfos clssinfo;
       
    
        public StudentList(int classId)
        {
            InitializeComponent();
           this.classId = classId;
           
        }
    
        private void AddButton_Clicked(object sender, EventArgs e)
        {
            if (StudentEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
    
            }
            else
            {
                conn = new SQLiteConnection(App.Database);
                conn.CreateTable<StudentInfo>();
                StudentInfo studentinfo = new StudentInfo()
                {
                    studentName = StudentEntry.Text,
                };
                
                var data =conn.Table<ClassInfos>();
                int id = Convert.ToInt32(classId);
                var data1 = (from values in data where values.ClassId == id select values).Single();
                data1.Students = new List<StudentInfo>();//  { studentinfo };
                conn.Insert(studentinfo);
                data1.Students.Add(studentinfo);
                conn.UpdateWithChildren(data1);
                //var data2 = conn.GetWithChildren<ClassInfos>(data1.ClassId, recursive: true);
               // conn.GetWithChildren<StudentInfo>(studentinfo.StudentId, recursive: true);
               
                StudentEntry.Text = "";
                 
    
            }
    
        }
        protected override void OnAppearing()
        {
            base.OnAppearing();
            conn = new SQLiteConnection(App.Database);
            int id = Convert.ToInt32(classId);
            List<StudentInfo> list = conn.GetAllWithChildren<StudentInfo>().Where(c => c.Classid == id).ToList();
            Studentlist.ItemsSource =list;
    
             
        }
    }
    

    Sir Just for once Watch it from up to down & give me idea to retrive the all the children.

  • shiwamshiwam Member ✭✭

    protected override void OnAppearing()
    {
    base.OnAppearing();
    using (conn = new SQLiteConnection(App.Database))
    {
    // var datas = conn.Table().Where(c => c.ClassId == classId);
    // var data = (from values in datas where values.ClassId == classId select values).Single();
    //IEnumerable<List> result = datas.Select(x => x.Students);
    // Studentlist.ItemsSource = result;
    conn = new SQLiteConnection(App.Database);
    var list= conn.Table().Where(c => c.Classid == classId).ToList();
    Studentlist.ItemsSource = list;
    // List list = conn.GetAllWithChildren().Where(c => c.Classid == id).ToList();
    /// Studentlist.ItemsSource =list;
    }

    i have used this method to retrive all the children but i failed it only return one children which is last inserted to the list.& previous one get overwrite in view.

  • ColeXColeX Member, Xamarin Team Xamurai

    @shiwam said:
    protected override void OnAppearing()
    {
    base.OnAppearing();
    using (conn = new SQLiteConnection(App.Database))
    {
    // var datas = conn.Table().Where(c => c.ClassId == classId);
    // var data = (from values in datas where values.ClassId == classId select values).Single();
    //IEnumerable<List> result = datas.Select(x => x.Students);
    // Studentlist.ItemsSource = result;
    conn = new SQLiteConnection(App.Database);
    var list= conn.Table().Where(c => c.Classid == classId).ToList();
    Studentlist.ItemsSource = list;
    // List list = conn.GetAllWithChildren().Where(c => c.Classid == id).ToList();
    /// Studentlist.ItemsSource =list;
    }

    i have used this method to retrive all the children but i failed it only return one children which is last inserted to the list.& previous one get overwrite in view.

    List list = conn.GetAllWithChildren().ToList();

  • shiwamshiwam Member ✭✭

    @ColeX said:

    @shiwam said:
    protected override void OnAppearing()
    {
    base.OnAppearing();
    using (conn = new SQLiteConnection(App.Database))
    {
    // var datas = conn.Table().Where(c => c.ClassId == classId);
    // var data = (from values in datas where values.ClassId == classId select values).Single();
    //IEnumerable<List> result = datas.Select(x => x.Students);
    // Studentlist.ItemsSource = result;
    conn = new SQLiteConnection(App.Database);
    var list= conn.Table().Where(c => c.Classid == classId).ToList();
    Studentlist.ItemsSource = list;
    // List list = conn.GetAllWithChildren().Where(c => c.Classid == id).ToList();
    /// Studentlist.ItemsSource =list;
    }

    i have used this method to retrive all the children but i failed it only return one children which is last inserted to the list.& previous one get overwrite in view.

    List list = conn.GetAllWithChildren().ToList();

    I've tried this already but i dont know why it only retrive the data which is last inserted & previous data is lost.There's always one child only i can add.I am doing mistake while retriving the data but i don't have idea .

  • ColeXColeX Member, Xamarin Team Xamurai

    It is weird , conn.GetAllWithChildren().ToList(); returns all the student i added .

  • shiwamshiwam Member ✭✭
    edited February 2020

    @ColeX said:
    It is weird , conn.GetAllWithChildren().ToList(); returns all the student i added .

    ya it returns all the children but all the children populate in every parents so i did linq operation by matching the children foreign key with parents id to get the child of respected parents.

                    var datas = conn.GetAllWithChildren<StudentInfo>().ToList();
                    var data = (from stds in datas where stds.Classid == Parents.ClassId select stds).ToList();
                    Studentlist.ItemsSource = data;
    
  • shiwamshiwam Member ✭✭
    edited February 2020

    though it won't work I have already tried each & everything You said me till now.So i come to the discussion page..But every logic i used to retrive i failed

  • shiwamshiwam Member ✭✭

    I think problem is with ForeignKey..it only assign to the one item at a time.After inserting next subitem then previous ForeignKey value of subitem becomes 0.

  • shiwamshiwam Member ✭✭

    I did it now but without subcollection in model

  • shiwamshiwam Member ✭✭
    Accepted Answer

    //////////////////////////////Model/////////////////////////////////////
    public class ClassInfos
    {
    [PrimaryKey, AutoIncrement]
    public int ClassId { get; set; }
    public string ClassName { get; set; }

    }
    

    public class StudentInfo
    {
    [PrimaryKey, AutoIncrement]
    public int StudentId { get; set; }
    public int Classid { get; set; }
    public string studentName { get; set; }

    }
    

    /////////////////////////first page////////////////////////////////////////////////////////////
    public SQLiteConnection conn;
    public MainPage()
    {
    InitializeComponent();
    using (conn = new SQLiteConnection(App.Database))
    {
    conn.CreateTable();
    var data = conn.Table().OrderBy(c => c.ClassId).ToList();

                Datalist.ItemsSource = data;
            }
        }
    
        public void AddButton_Clicked(object sender, EventArgs e)
        {
            if (ClassEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
            }
            else
            {
                using (conn = new SQLiteConnection(App.Database))
                {
                    conn.CreateTable<ClassInfos>();
                    ClassInfos classinfo = new ClassInfos
                    {
                        ClassName = ClassEntry.Text
                    };
    
                    conn.Insert(classinfo);
                    DisplayAlert(classinfo.ClassName, "Saved", "Ok");
                    Navigation.PopToRootAsync();
                    ClassEntry.Text = "";
                }
            }
    
        }
    

    ///////////////////////////////////Second Page///////////////////
    SQLiteConnection conn;
    ClassInfos Info;
    public StudentList(ClassInfos Infos)
    {
    InitializeComponent();
    this.Info = Infos;
    }

        private void AddButton_Clicked(object sender, EventArgs e)
        {
            if (StudentEntry.Text == null)
            {
                DisplayAlert(null, "Null Value", "Ok");
    
            }
            else
            {
                try
                {
                    using (conn = new SQLiteConnection(App.Database))
                    {
                        StudentInfo std = new StudentInfo();
                        std.studentName = StudentEntry.Text;
                        std.Classid = Info.ClassId;///here assigning the parents id to Student TAble
                        conn.CreateTable<StudentInfo>();
                        conn.Insert(std);
                    }
                        StudentEntry.Text = "";
                }
                catch(Exception ex)
                {
                    DisplayAlert("Message", ex.Message, "Ok");
                }
    
            } 
        }
        protected override void OnAppearing()
        {
            base.OnAppearing();
            try
            {
                using (conn = new SQLiteConnection(App.Database))
                {
                    var data = conn.Table<StudentInfo>().Where(c => c.Classid == Info.ClassId);//Getting the child 
                    Studentlist.ItemsSource = data;
                }   
            }
            catch (Exception ex)
            { 
    
                DisplayAlert("Message",ex.Message , "Ok");
            }
    
        }
    }
    
Sign In or Register to comment.