Mostrando las entradas con la etiqueta Desarrollo Mobile. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Desarrollo Mobile. Mostrar todas las entradas

domingo, 3 de mayo de 2020

Xamarin.Forms - Tabbed Page con SQLite - Parte 2

Hola nuevamente; espero estén todos bien, hoy les comparto la parte de 2 del control Tabbed Page. Implementaremos el Tabbed Page Info (información de usuario como nombres, apellidos, fecha de nacimiento, teléfono celular, tipo de persona y datos del médico tratante como el teléfono y el e-mail).

Requisitos:
Microsoft Visual Studio Community 2019.
Xamarin.Froms - XAML.
SQLite - Gestión de datos local.
Revisar - Tabbed Page con SQLite - Parte 1

Diseño de Interfaz:
Ahora en la pagina TabPageInfo.xaml agregamos los siguientes elementos, además importar la referencia TabPageInfo (agregar la siguiente línea xmlns:local="clr-namespace:AppDIAbetes.Views.Options.TabPageInfo"):

<?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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="AppDIAbetes.Views.Options.TabPageInfo"
             Title="Info"
             IconImageSource="UserInfo32.png"
             BackgroundColor="#FFFFFF">
    <ContentPage.Content>
        <AbsoluteLayout BackgroundColor="White" Margin="5,0,5,5">
            <FlexLayout IsVisible="True" JustifyContent="SpaceEvenly" Direction="Column" AlignItems="Center" Margin="10,0,10,0" >
                    <Grid BackgroundColor="Transparent">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="*" />
                            <RowDefinition Height="*" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                    <StackLayout Grid.Row="0" Grid.Column="0" Grid.RowSpan="3">
                        <Frame>
                            <Image x:Name="photoUser" HorizontalOptions="Center" HeightRequest="158" WidthRequest="120" BackgroundColor="Transparent"/>
                        </Frame>
                    </StackLayout>                       
                    <!--</Frame>-->
                        <StackLayout Grid.Row="0" Grid.Column="1">
                            <Entry x:Name="entryFirstName" Placeholder="Nombres" Keyboard="Text" FontSize="Small" TextColor="Black"/>
                        </StackLayout>

                        <StackLayout Grid.Row="1" Grid.Column="1">
                            <Entry x:Name="entryLastName" Placeholder="Apellidos" Keyboard="Text" FontSize="Small" TextColor="Black"/>
                        </StackLayout>

                        <StackLayout Grid.Row="2" Grid.Column="1" HorizontalOptions="Start" Orientation="Horizontal">
                            <Label Text="Fecha Nac." TextColor="Black" HorizontalOptions="Start" VerticalOptions="Center" FontSize="Small"/>

                        <DatePicker Format="dd/MM/yyyy" Grid.Row="2" Grid.Column="1"
                                         x:Name="dpFechaNac" TextColor="Black" FontSize="Small"           
                                         HorizontalOptions="EndAndExpand"  BackgroundColor="Transparent"
                                         MinimumDate="01/01/1920" MaximumDate="12/31/2030" />
                        </StackLayout>

                        <StackLayout Grid.Row="3" Grid.Column="1" HorizontalOptions="Start" Orientation="Horizontal">
                            <Label Text="(+51)" TextColor="Black" HorizontalOptions="Start" VerticalOptions="Center" FontSize="Small"/>
                            <Entry x:Name="entryPhone" Placeholder="Celular" MaxLength="9" Keyboard="Telephone" FontSize="Small" TextColor="Black" WidthRequest="120"/>
                        </StackLayout>                   

                        <StackLayout Grid.Row="3" Grid.Column="0" HorizontalOptions="Center" Orientation="Horizontal">
                            <ImageButton x:Name="selPhoto" Clicked="selPhoto_Clicked" Source="folderPictures48.png"/>
                            <ImageButton x:Name="takePhoto" Clicked="takePhoto_Clicked" Source="folderPhoto48.png"/>
                        </StackLayout>

                        <StackLayout Grid.Row="4" Grid.ColumnSpan="2" HorizontalOptions="CenterAndExpand" Orientation="Horizontal">
                            <Label Grid.Column="0" Text="Tipo de Persona" TextColor="Black" WidthRequest="110" HorizontalOptions="Start" VerticalOptions="Center" FontSize="Small"/>
                            <Picker Grid.Column="1"
                                    x:Name="pTipyPeople"
                                    Title="Seleccionar" FontSize="Small"
                                    TextColor="Black" WidthRequest="208"
                                    SelectedIndexChanged="OnPickerSelectedIndexChanged">
                                <Picker.Items>
                                    <x:String>PACIENTE</x:String>
                                    <x:String>MÉDICO TRATANTE</x:String>
                                </Picker.Items>
                            </Picker>
                        </StackLayout>
                    </Grid>
              
                    <Label x:Name="warningPhone" Text="" IsVisible="False" TextColor="#FF5959" FontSize="12" BackgroundColor="Transparent" FlexLayout.AlignSelf="End"/>

                    <StackLayout HorizontalOptions="Start" Orientation="Horizontal">
                        <Label x:Name="labelPhoneMedico" Text="N° Teléfono" TextColor="Black" WidthRequest="100" HorizontalOptions="Start" VerticalOptions="Center" FontSize="Small" IsVisible="False"/>
                        <Entry x:Name="entryPhoneMedico" Placeholder="Teléf de tu médico tratante" Keyboard="Telephone" FontSize="Small" TextColor="Black" WidthRequest="210" IsVisible="False"/>
                    </StackLayout>

                    <StackLayout HorizontalOptions="Start" Orientation="Horizontal">
                        <Label x:Name="labelEmailMedico" Text="Email" TextColor="Black" WidthRequest="100" HorizontalOptions="Start" VerticalOptions="Center" FontSize="Small" IsVisible="False"/>
                        <Entry x:Name="entryEmailMedico" Placeholder="Email de tu médico tratante" Keyboard="Email" FontSize="Small" TextColor="Black" WidthRequest="210" IsVisible="False" />
                    </StackLayout>

                    <Button x:Name="infoInsert" Clicked="infoInsert_Clicked" FontSize="Medium" TextColor="White" BorderColor="Black" BackgroundColor="#6fb7ff"  CornerRadius="5" FlexLayout.AlignSelf="Stretch" Text="Actualizar"></Button>
               
            </FlexLayout>
        </AbsoluteLayout>
    </ContentPage.Content>   

</ContentPage>

Crear Clases:
Seguidamente creamos la clase People.cs en el sub directorio Views\Models y agregamos los siguientes atributos:

using SQLite;
using System;

namespace AppDIAbetes.Models
{                
    public class People
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }
        public DateTime birthdate { get; set; }
        public string phoneUser { get; set; }
        public string phoneMedico { get; set; }
        public string emailMedico { get; set; }
        public int IdUser { get; set; }
        public int IdRole { get; set; }
        public DateTime regDate { get; set; }
        public DateTime updDate { get; set; }
        public bool chkViewPass { get; set; }
        public bool chkChangePass { get; set; }
        public bool chkSendReport { get; set; }
    }
}

Para finalizar creamos la clase PeopleDB.cs en el sub directorio Views\Data y agregamos las siguientes funciones para dar la funcionalidad con conexión a base de datos del SQLite (la región conexionbd son instrucciones de conexión a la base de datos):

using AppDIAbetes.Models;
using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AppDIAbetes.Data
{
    public class PeopleDB
    {
        #region conexionbd
        static readonly Lazy<SQLiteAsyncConnection> lazyInitializer = new Lazy<SQLiteAsyncConnection>(() =>
        {
            return new SQLiteAsyncConnection(DataBase.DatabasePath, DataBase.Flags);
        });

        static SQLiteAsyncConnection Database => lazyInitializer.Value;
        static bool initialized = false;

        public PeopleDB()
        {
            InitializeAsync().SafeFireAndForget(false);
        }

        async Task InitializeAsync()
        {
            if (!initialized)
            {
                if (!Database.TableMappings.Any(m => m.MappedType.Name == typeof(People).Name))
                {
                    await Database.CreateTablesAsync(CreateFlags.None, typeof(People)).ConfigureAwait(false);
                    initialized = true;
                }
            }
        }
        #endregion

        #region metodos crud 
        public Task<List<People>> peopleFillIdUse(int intIdUser)
        {
            return Database.QueryAsync<People>("Select * from People Where IdUser=?", intIdUser);
        }

        public string savePeopleInfo(People people)
        {
            string srtResult = null;

            IEnumerable<People> result = valPeople(people.IdUser);
            if(result.Count()== 0) {
                Database.InsertAsync(people);
                srtResult = "Ins";
            }
            else{
                Database.QueryAsync<People>("Update People Set firstName=?, lastName=?, birthdate=?, phoneUser=?, phoneMedico=?, emailMedico=?, IdRole=?, updDate=? Where Id=? and IdUser=?", people.firstName, people.lastName, people.birthdate, people.phoneUser, people.phoneMedico, people.emailMedico, people.IdRole, people.updDate, people.Id, people.IdUser);
                srtResult = "Upd";
            }
            return srtResult;
        }

        public string savePeopleConfig(People people)
        {
            string srtResult = null;
        
            Database.QueryAsync<People>("Update People Set chkViewPass=?, chkChangePass=?, chkSendReport=?, updDate=? Where Id=? and IdUser=?", people.chkViewPass, people.chkChangePass, people.chkSendReport, people.updDate, people.Id, people.IdUser);
            srtResult = "Upd";
            return srtResult;
        }

        public IEnumerable<People> valPeople(int intIdUser)
        {
            var result = Database.QueryAsync<People>("Select * from People p, User u Where p.IdUser=u.Id and p.IdUser=?", intIdUser);
            return result.Result;
        }
        #endregion
    }

}

Implementar el CodeBehind:
El en CodeBehind de la pagina de contenido TabPageInfo.xaml.cs creamos las siguientes instrucciones (la sección sombreado de color //Managing user session corresponde a capturar de la sesión de logeo):

using AppDIAbetes.Utility;
using Plugin.Media;
using Plugin.Media.Abstractions;
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using AppDIAbetes.Models;
using AppDIAbetes.Data;

namespace AppDIAbetes.Views.Options
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class TabPageInfo : ContentPage
    {
        //Managing user session
        private string strAuthentifyUser;
        public static string sstrEmailUser;
        LoginAccess OAuthLogin = new LoginAccess(sstrEmailUser);

        private int intId, intIdUser;
        private string strUser;

        People people = new People();
        PeopleDB peopleDB = new PeopleDB();
        UserDB userDB = new UserDB();

        public TabPageInfo()
        {
            strAuthentifyUser = OAuthLogin.AuthentifyLogin();
            InitializeComponent();
            this.BindingContext = new Models.CamarePhoto();
            vCaptureIdUser();
        }

        private async void vCaptureIdUser() {
            IList<User> result = await userDB.userFillEmail(strAuthentifyUser);

            if (result.Count == 1)
            {
                foreach (var item in result)
                {
                    intIdUser = item.Id;//Id de la tabla User
                    strUser = item.name;
                }
            }
            else {
                await DisplayAlert("Alerta", "Ocurrio un problema al cargar los registros.", "Aceptar");
            }
        }

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

            IList<People> result = await peopleDB.peopleFillIdUse(intIdUser);

            foreach (var item in result)
            {
                intId = item.Id;
                entryFirstName.Text = item.firstName;
                entryLastName.Text = item.lastName;
                dpFechaNac.Date = item.birthdate;
                entryPhone.Text = item.phoneUser;
                pTipyPeople.SelectedIndex = item.IdRole;

                entryPhoneMedico.Text = item.phoneMedico;
                entryEmailMedico.Text = item.emailMedico;
            }
        }

        #region control type people
        void OnPickerSelectedIndexChanged(object sender, EventArgs e)
        {
            var picker = (Picker)sender;
            int selectedIndex = picker.SelectedIndex;

            if (selectedIndex != -1)
            {
                if (selectedIndex == 0)// 0 PACIENTE
                {
                    labelPhoneMedico.IsVisible = true;
                    entryPhoneMedico.IsVisible = true;
                    labelEmailMedico.IsVisible = true;
                    entryEmailMedico.IsVisible = true;
                }
                else if(selectedIndex == 1) {//1 MEDICO TRATANTE
                    labelPhoneMedico.IsVisible = false;
                    entryPhoneMedico.IsVisible = false;
                    labelEmailMedico.IsVisible = false;
                    entryEmailMedico.IsVisible = false;
                }
            }
        }
        #endregion

        #region CRUD
        private async void infoInsert_Clicked(object sender, EventArgs e)
        {
            people.Id = intId;//Id de la tabla People
            people.firstName = entryFirstName.Text;
            people.lastName = entryLastName.Text;
            people.birthdate = dpFechaNac.Date;
            people.phoneUser = entryPhone.Text;
            people.phoneMedico = entryPhoneMedico.Text;
            people.emailMedico = entryEmailMedico.Text;

            people.IdUser = intIdUser;//Id de la tabla User
            people.IdRole = pTipyPeople.SelectedIndex;        

            if (people.Id == 0)
            {
                people.regDate = DateTime.Now;
                people.updDate = DateTime.Now;

                people.chkViewPass = false;
                people.chkChangePass = false;
                people.chkSendReport = false;

                var returnResult = peopleDB.savePeopleInfo(people);
                if (returnResult == "Ins")
                    await DisplayAlert("Aviso", "Registros ingresado con éxito.", "Aceptar");
            }
            else {
                people.updDate = DateTime.Now;

                var returnResult = peopleDB.savePeopleInfo(people);
                if (returnResult == "Upd")
                    await DisplayAlert("Aviso", "Registros actualizado con éxito.", "Aceptar");
            }
        }
        #endregion       
    }
}

Resultado:
Interfaz de la página TabPageInfo de tipo de Pagina de Contenido (la sección de tomar foto o cargar imagen lo veremos en otro artículo):
XAML TabPageInfo.xaml 
En la parte 3 revisaremos 👀la implementación de la interfaz TabPageConfig.xaml y el desarrollo de su CodeBehind del TabPageConfig.xaml.cs.

De todas maneras gratitud a Dios 😊 y gracias a todos ustedes por la acogida de este nuevo articulo, éxitos y bendiciones 🙏 y un gran abrazo a todos ✌...!!!