Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

save picker options from collectionview to database

ycusoyycusoy Member ✭✭

I created a list of attendance in xaml with 3 tables.
1. The first table is the date that I put in the picker.
2. The second table is the name of the students that I put in the collectionview along with a picker containing 4 options.
3. The third table is attendance, which is stored in the database.

this is an example of c# ..

using AdmKelas.Models;
using System;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Collections.Generic;
using System.Linq;

namespace AdmKelas.Halaman
{
    [DesignTimeVisible(false)]
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class EditAbsen : ContentPage
    {

        public EditAbsen()
        {
            InitializeComponent();
        }
        protected override async void OnAppearing()
        {
            List<Siswa> sis = await App.Dtsekolah.GetSiswaAsync();
            daftarSiswa.ItemsSource = sis;
            List<Kalpen> kal = await App.Dtsekolah.GetKalpenAsync();
            tglKalpen.ItemsSource = kal;
            base.OnAppearing();
        }
        async void SimpanData(object sender, EventArgs e)
        {
            var absen = (Absen)BindingContext;
            await DisplayAlert("Sukses!", "Data tersimpan", "Ok");
            await App.Dtsekolah.SaveAbsenAsync(absen);
            await Navigation.PopAsync();
        }
        async void HapusData(object sender, EventArgs e)
        {
            var result = await DisplayAlert("Peringatan!", "Data absen ini akan dihapus?", "Ya", "Batal");

            if (result == true)
            {
                var absen = (Absen)BindingContext;
                await App.Dtsekolah.DeleteAbsenAsync(absen);
                await Navigation.PopAsync();
            }
            else
            { return; }
        }
    }
}

code xaml.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:abstractions="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin" 
             xmlns:local="clr-namespace:AdmKelas.CS"
             NavigationPage.HasNavigationBar="False"
             x:Class="AdmKelas.Halaman.EditAbsen">
    <ContentPage.Content>
        <StackLayout>
            <Grid Margin="20,20,20,0" HeightRequest="120">
                <!--<Entry x:Name="en1" IsVisible="false" Text="{Binding HariAbsen}"/> SelectedIndexChanged="Pick"-->
                <Frame Style="{StaticResource FrameBox}">
                    <local:CustomPicker Style="{StaticResource pickr}" 
                                        Title="Tanggal"
                                        x:Name="tglKalpen"
                                        SelectedItem="{Binding HariAbsen}"
                                        ItemDisplayBinding="{Binding Tanggal, StringFormat='{0:dddd, dd MMMM yyyy}'}" 
                                        HorizontalOptions="Center">
                    </local:CustomPicker>
                </Frame>
                <Label Text=" calendar-alt Tanggal " Style="{StaticResource LabelFrame}" HorizontalOptions="Center" FontSize="16"/>
            </Grid>
            <CollectionView x:Name="daftarSiswa" 
                            Margin="20,0,20,20"
                            SelectionMode="None"
                            ItemsLayout="VerticalGrid,2"
                            HorizontalOptions="StartAndExpand"
                            VerticalOptions="CenterAndExpand"
                            EmptyView="Belum ada data yang ditampilkan. Anda harus memasukan data terlebih dahulu dengan mengabsen siswa sesuai tanggal.">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <BoxView BackgroundColor="Black" Opacity="0.1" HeightRequest="1"/>
                            <Grid ColumnDefinitions="0.7*,*" Padding="6">
                                <Grid Grid.Column="0">
                                    <BoxView HeightRequest="1" HorizontalOptions="StartAndExpand" WidthRequest="1"
                                             Color="Goldenrod"/>
                                    <Grid HorizontalOptions="CenterAndExpand">
                                        <abstractions:CircleImage Source="{Binding FotoSiswa}"
                                                                  Aspect="AspectFill"
                                                                  HeightRequest="60"
                                                                  WidthRequest="60"
                                                                  BorderColor="Goldenrod"
                                                                  BorderThickness="1"
                                                                  Margin="6" />
                                        <Label Text="{Binding NamaKecil}"
                                               BackgroundColor="Black"
                                               VerticalOptions="Center"
                                               HorizontalOptions="EndAndExpand"
                                               TextColor="gold"
                                               FontSize="12"
                                               Padding="5,0,5,0"
                                               FontAttributes="Bold"
                                               Margin="10,0,0,-50"/>
                                    </Grid>
                                </Grid>
                                <Grid Grid.Column="1" HorizontalOptions="CenterAndExpand">
                                    <local:CustomPicker Style="{StaticResource pickr}" Title="Absen" SelectedItem="{Binding CekList}">
                                        <local:CustomPicker.ItemsSource>
                                            <x:Array Type="{x:Type x:String}">
                                                <x:String>Hadir</x:String>
                                                <x:String>Sakit</x:String>
                                                <x:String>Izin</x:String>
                                                <x:String>Alpa</x:String>
                                            </x:Array>
                                        </local:CustomPicker.ItemsSource>
                                    </local:CustomPicker>
                                    <!--<RadioButton Text="Hadir" />
                                    <RadioButton Text="Sakit"/>
                                    <RadioButton Text="Izin"/>
                                    <RadioButton Text="Alpa"/>-->
                                </Grid>
                            </Grid>
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
            <BoxView BackgroundColor="Transparent" HeightRequest="1" Margin="-10" 
                     HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
            <AbsoluteLayout>
                <StackLayout AbsoluteLayout.LayoutBounds="0,1,1,60"
                             AbsoluteLayout.LayoutFlags="XProportional,YProportional,WidthProportional">
                    <StackLayout Orientation="Horizontal" 
                                 Padding="8"
                                 BackgroundColor="#2196F3">
                        <Button Style="{StaticResource butn}" Text="times-circle"  BackgroundColor="#EC2B4F" TextColor="AliceBlue" Clicked="HapusData" />
                        <Button Style="{StaticResource butn}" Text="check-circle" BackgroundColor="#7DDA49" TextColor="#0A402C" Clicked="SimpanData"/>
                    </StackLayout>
                </StackLayout>
            </AbsoluteLayout>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

how to write code behind the xaml to enter data into the third table?

Tagged:

Best Answers

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    Accepted Answer

    Try creating a property in the model class to store the selected data, you could pass the slected data to the property in the SelectedIndexChanged event.

    Check the code:

    <CollectionView ItemsSource="{Binding DataCollection}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout>
                    ...
                    <Picker Title="Absen" SelectedItem="{Binding SelectedData}" SelectedIndexChanged="Picker_SelectedIndexChanged">
                        <Picker.ItemsSource>
                            <x:Array Type="{x:Type x:String}">
                                <x:String>Hadir</x:String>
                                <x:String>Sakit</x:String>
                                <x:String>Izin</x:String>
                                <x:String>Alpa</x:String>
                            </x:Array>
                        </Picker.ItemsSource>
                    </Picker>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    
    <Button Text="Submit" Clicked="SubmitClickedEvent"/>
    

    Page.xaml.cs

    public partial class MainPage : ContentPage
    {
        TestViewModel viewModel;
        ObservableCollection<TestModel> dataCollection;
        public MainPage()
        {
            InitializeComponent();
    
            viewModel = new TestViewModel();
            dataCollection = viewModel.DataCollection;
    
            BindingContext = viewModel;
        }
    
        private void Picker_SelectedIndexChanged(object sender, EventArgs e)
        {
            var picker = sender as Picker;
    
            var index = picker.SelectedIndex;
            var list = picker.ItemsSource;
    
            var model = picker.BindingContext as TestModel;
            model.SelectedData = (string)list[index];
        }
    
        private void SubmitClickedEvent(object sender, EventArgs e)
        {
            //the picked item has been saved to the SelectedData property, you could store the data to the database with the model
        }
    }
    
  • YelinzhYelinzh Member, Xamarin Team Xamurai
    Accepted Answer

    Sorry, I cannot reproduce the issue on my side to get the cause. You could check the code of the comment I posted before.
    https://forums.xamarin.com/discussion/comment/429569/#Comment_429569

    And here is the related code about the model class and viewModel class.

    public class TestViewModel
    {
        public ObservableCollection<TestModel> ContentCollection { get; set; }
    
        public TestViewModel()
        {
            ContentCollection = new ObservableCollection<TestModel>();
            //add the data
        }
    }
    
    public class TestModel : INotifyPropertyChanged
    {
        private View content;
        public View Content
        {
            get
            {
                return content;
            }
            set
            {
                if (content != value)
                {
                    content = value;
                    NotifyPropertyChanged("Content");
                }
            }
        }
        protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

Answers

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    The Picker class provides the SelectedIndexChanged event which is raised when the value of the SelectIndex property has changed. You could detect the event to get the setion data and save it to the database.

    <Picker ... SelectedIndexChanged="Picker_SelectedIndexChanged"/>
    

    SelectedIndexChanged event

    private void Picker_SelectedIndexChanged(object sender, EventArgs e)
    {
        var _picker = sender as Picker;
        var index = _picker.SelectedIndex;
    
        //get the data with the index from model class and save it to the database
    }
    

    Xamarin forums are migrating to a new home on Microsoft Q&A!
    We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For more information, please refer to this sticky post.

  • ycusoyycusoy Member ✭✭
    edited February 17

    This is precisely what then becomes my question, how will I save it to the database whereas I don't know how to make a picker that can summarize data one by one into the CekList column table from the attendance table. It will seem easier to me when fetching data manually with one entry, rather than retrieving data from within a collectionview where there are various attendance options. shortcuts as below ...

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    Accepted Answer

    Try creating a property in the model class to store the selected data, you could pass the slected data to the property in the SelectedIndexChanged event.

    Check the code:

    <CollectionView ItemsSource="{Binding DataCollection}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout>
                    ...
                    <Picker Title="Absen" SelectedItem="{Binding SelectedData}" SelectedIndexChanged="Picker_SelectedIndexChanged">
                        <Picker.ItemsSource>
                            <x:Array Type="{x:Type x:String}">
                                <x:String>Hadir</x:String>
                                <x:String>Sakit</x:String>
                                <x:String>Izin</x:String>
                                <x:String>Alpa</x:String>
                            </x:Array>
                        </Picker.ItemsSource>
                    </Picker>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    
    <Button Text="Submit" Clicked="SubmitClickedEvent"/>
    

    Page.xaml.cs

    public partial class MainPage : ContentPage
    {
        TestViewModel viewModel;
        ObservableCollection<TestModel> dataCollection;
        public MainPage()
        {
            InitializeComponent();
    
            viewModel = new TestViewModel();
            dataCollection = viewModel.DataCollection;
    
            BindingContext = viewModel;
        }
    
        private void Picker_SelectedIndexChanged(object sender, EventArgs e)
        {
            var picker = sender as Picker;
    
            var index = picker.SelectedIndex;
            var list = picker.ItemsSource;
    
            var model = picker.BindingContext as TestModel;
            model.SelectedData = (string)list[index];
        }
    
        private void SubmitClickedEvent(object sender, EventArgs e)
        {
            //the picked item has been saved to the SelectedData property, you could store the data to the database with the model
        }
    }
    
  • ycusoyycusoy Member ✭✭

    thank you, but what you give out is very far from my question. How then will I change the structure of my application?

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    how will I save it to the database whereas I don't know how to make a picker that can summarize data one by one into the CekList column table from the attendance table.

    Sorry for that if I misunstand your need. According to the posted screenshot, the function seems to storing the all picked info when clicking the ok button. Please point out where is the mistake.

  • ycusoyycusoy Member ✭✭
    edited February 19

    I mean a question, does my structure need to be changed?
    because I see a difference there from what you share. Sorry if I don't understand .. :)
    I don't know where this red line came from

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    I don't know where this red line came from

    I just created a basic demo to achieve the function, you could refer to this code. Please replace the ViewModel with the class in your project.

  • ycusoyycusoy Member ✭✭

    still red line .. :(
    I don't understand how that can happen, but I have a class from which data is fetched.

    protected override async void OnAppearing()
            {
                List<Siswa> sis = await App.Dtsekolah.GetSiswaAsync();
                **daftarSiswa**.ItemsSource = sis;
                List<Kalpen> kal = await App.Dtsekolah.GetKalpenAsync();
                tglKalpen.ItemsSource = kal;
                base.OnAppearing();
            }
    

    and these class:

    public class Siswa
        {   
            [PrimaryKey, AutoIncrement]
            public int IdSis { get; set; }
            public string NamaSiswa { get; set; }
    }
    public class Kalpen
        {
            [PrimaryKey, AutoIncrement]
            public int IdKal { get; set; }
            public DateTime Tanggal { get; set; }
    }
     public class Absen
        {
            [PrimaryKey, AutoIncrement]
            public int IdAbs { get; set; }
            public DateTime Tanggal { get; set; }// from Kalpen
            public string NamaSiswa { get; set; } // from Siswa
            public string CekList { get; set; }
        }
    
    <CollectionView x:Name=**"daftarSiswa"** Grid.Row="1"
                                ItemsSource=**"{Binding DataCollection}"**
    

    dataCollection = viewModel.DataCollection;
    BindingContext = viewModel;

    Is it possible to retrieve data from 2 tables?

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    How did you set bindingContext for the contentPage that displays the collectionview?

  • ycusoyycusoy Member ✭✭

    I call data from 2 class using functions OnAppearing()

    for this picker:

    <local:CustomPicker Title="Tanggal"
                        x:Name="tglKalpen"
                        SelectedItem="{Binding HariAbsen}"
                        ItemDisplayBinding="{Binding Tanggal, StringFormat='{0:dddd, dd MMMM yyyy}'}" 
                        ....
    </local:CustomPicker>
    

    I use class Kalpen and enter data with representatives x:Name="tglKalpen".
    from the SelectedItem results, I will save it to class Absen with {Binding HariAbsen}.

    for this collectionview :

    <CollectionView x:Name="daftarSiswa" 
                    Margin="20,0,20,20"
                    SelectionMode="None"
                    ItemsLayout="VerticalGrid,2"
                    .....
    

    I use class Siswa and enter data with representatives x:Name="daftarSiswa".
    in colectionview, I added picker with 4 options and from results of selecting this option, will save it to class Absen with {Binding Ceklist}.

    I save it with click button with async void SimpanData(object sender, EventArgs e).

    I use what is shared. and stuck in dataCollection = viewModel.DataCollection with a few red lines like before.
    I thought, the worst possibility would be to change class structure.

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    edited February 22

    and stuck in dataCollection = viewModel.DataCollection with a few red lines like before

    The 'TestViewModel' class should correspond to the 'Absen' class in your project. Try to change the code like below:

    Absen model; // get the instance of Absen class that you set binding for the collectionView
    var dataCollection = Absen.Ceklist;
    

    I use the mvvm mode to set data binding. Here is the related doc, you could refer to it.
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm

  • ycusoyycusoy Member ✭✭

    @Yelinzh said:

    I've tried, and got an error. after I looked back. there is an error in my class structure. I want to retrieve the date from the Kalpen class (1 column). but when I am going to collect Student and Checklist, it branches out to the number of students (many rows). apparently, there is something wrong with the Absen class.

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    Would you mind sharing a basic demo to reproduce the issue? It'll help to get the cause.

  • ycusoyycusoy Member ✭✭

    on the basis of the question I have written as above.
    and to connect to the database I followed the tutorial from docs.microsoft.com
    I think nothing I missed.

  • YelinzhYelinzh Member, Xamarin Team Xamurai
    Accepted Answer

    Sorry, I cannot reproduce the issue on my side to get the cause. You could check the code of the comment I posted before.
    https://forums.xamarin.com/discussion/comment/429569/#Comment_429569

    And here is the related code about the model class and viewModel class.

    public class TestViewModel
    {
        public ObservableCollection<TestModel> ContentCollection { get; set; }
    
        public TestViewModel()
        {
            ContentCollection = new ObservableCollection<TestModel>();
            //add the data
        }
    }
    
    public class TestModel : INotifyPropertyChanged
    {
        private View content;
        public View Content
        {
            get
            {
                return content;
            }
            set
            {
                if (content != value)
                {
                    content = value;
                    NotifyPropertyChanged("Content");
                }
            }
        }
        protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    
  • ycusoyycusoy Member ✭✭
    edited March 4
    > @Yelinzh
    okay, I will make a reference to learn from what you provide. I really admire you in answering questions. thank you for taking the time :)
  • ycusoyycusoy Member ✭✭

    I am back here again ..
    step by step above finally worked. but I don't know the method of saving one SelectedData column at the same time. above right consists of many students.

  • YelinzhYelinzh Member, Xamarin Team Xamurai

    but I don't know the method of saving one SelectedData column at the same time

    What's the problem? Could you post more details about that?


    Xamarin Community Forums is moving to Microsoft Q&A!
    For new questions: we invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For existing questions: follow up is still in service until April 15th, 2021.
    For more information, please refer to this sticky post.

Sign In or Register to comment.