Ir al contenido principal

Xamarin.Forms - CRUD con SQLite

En este post elaboraremos un ejemplo práctico del ya muy conocido como el CRUD, es decir Crear - Create, Leer - Read, Actualizar - Update y Eliminar - Delete de la entidad usuario (CRUD en inglés).

Nuevamente les dejo el link (App - DÍAbetes) donde se viene detallando todo lo elaborado acerca del diseño y desarrollo de la aplicación.

El ejemplo práctico será diseñada y desarrollada con Xamarin.Forms y a nivel de almacenamiento de datos en SQLite. Se hará uso de la solución y proyecto de nombre AppDIAbetes que contiene todo lo realizando en el proyecto AppLogin, claro esta que seguimos haciendo uso del IDE de Visual Studio y todas las pruebas se viene realizando en un equipo móvil físico con Sistema Operativo Android, recordándoles que esto no restringe el uso de emuladores.

Requisitos:
Microsoft Visual Studio Community 2019.
Xamarin.Froms - XAML.
SQLite - Gestión de datos local.

El proyecto AppLogin se renombro a AppDIAbetes:
Recordar que sólo se viene implementado el proyecto para la plataforma de Android desde el Visual Studio 2019.

Estructura del Proyecto:
La estructura del proyecto se mantiene, pero, con el incremento de los directorios y demás componentes que se crearon. Es decir los directorios ya creados como Data, Models y Views, durante toda la etapa de desarrollo de este proyecto móvil iremos agregando nuevas clases.

Clases creadas:
En las clases DataBase.cs, TaskExtensions.cs se mantiene las mismas instrucciones ya definidas (recordar que son instrucciones la generación y conexión a la base de datos); y en la clase UserDB.cs se agregaron las instrucciones equivales al CRUD y en la clase User.cs se agregaron nuevos atributos

Diseño de Interfaz:
En el directorio Views agregaremos nuevos elementos de tipo Página de Contenido para XAML de nombre de SignUpLogin.xaml (página para crear o agregar un nuevo usuario), UsersList.xaml (página para listar los usuarios creado) y UsersEdit.xaml (para actualiza o eliminar los usuarios - esto no quita a que se puede incluir la creación en esta pagina, es decir mantener las 3 operaciones en un sola página) cada archivo .xaml contienes su archivo de tipo CodeBehind con la extensión de xaml.cs; para aclarar que los archivo MainPage.xaml y Login.xaml agregados en el anterior post no se modificaron.

1. En el archivo SignUpLogin.xaml agregaremos las propiedades de:

    Image Source="LogoDIAbetes.jpg" ...
    Entry x:Name="entryEmail" ...
    Entry x:Name="entryName" ...
    Entry x:Name="entryPassword" ...
    Entry x:Name="entryConfPassword" ....
    Label x:Name="warningPassword" ...
    Entry x:Name="entryPhone" ...
    Label x:Name="warningPhone" ...
    Button x:Name="signUp" ... Botón para registrar.
    Button x:Name="listsignUp" Botón para ingresar a la lista de usuarios (uso temporal).

XAML completo del archivo SignUpLogin.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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="AppDIAbetes.Views.SignUpLogin" Title="Regístrese aquí">
    <ContentPage.ToolbarItems>
        <ToolbarItem Priority="1" />
    </ContentPage.ToolbarItems>
    <ContentPage.Content>       
        <AbsoluteLayout Margin="5,0,5,5">
            <FlexLayout IsVisible="True" JustifyContent="SpaceEvenly" Direction="Column" AlignItems="Center" Margin="30,0,30,0" >
                <Image Source="LogoDIAbetes.jpg" HeightRequest="140" WidthRequest="140" FlexLayout.AlignSelf="Center" BackgroundColor="Transparent" />
                <Entry x:Name="entryEmail" Placeholder="Email" Keyboard="Email" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Entry x:Name="entryName" Placeholder="Nombre" Keyboard="Text" MaxLength="10" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Entry x:Name="entryPassword" Placeholder="Contraseña" Keyboard="Text" MaxLength="12" IsPassword="True" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black"/>                <Entry x:Name="entryConfPassword" Placeholder="Confirmar Contraseña" MaxLength="12" IsPassword="True" FontSize="Small" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Label x:Name="warningPassword" Text="" IsVisible="False" TextColor="Blue" FontSize="12" BackgroundColor="Transparent" FlexLayout.AlignSelf="End"/>
                <Entry x:Name="entryPhone" Placeholder="Celular" MaxLength="9" Keyboard="Telephone" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Label x:Name="warningPhone" Text="" IsVisible="False" TextColor="Blue" FontSize="12" BackgroundColor="Transparent" FlexLayout.AlignSelf="End"/>                -->
                <Button x:Name="signUp" Clicked="signUp_Clicked" FontSize="Medium" TextColor="White" BorderColor="Black" BackgroundColor="#00b33c"  CornerRadius="5" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand" Text="Registrese"></Button>
                <Button x:Name="listsignUp" Clicked="listsignUp_Clicked" FontSize="Medium" TextColor="White" BorderColor="Black" BackgroundColor="#00b33c"  CornerRadius="5" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand" Text="Ver Lista"></Button>               
            </FlexLayout>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

2. En el archivo UsersList.xaml agregaremos las propiedades de:   
En la sección ContentPage.ToolbarItems agregaremos el Clicked y TypeArguments
   
    <ContentPage.ToolbarItems>
        <ToolbarItem Clicked="OnItemAdded">
            <ToolbarItem.IconImageSource>
                <OnPlatform x:TypeArguments="ImageSource">
                    <On Platform="Android" Value="AddUser24.png" />
                </OnPlatform>
            </ToolbarItem.IconImageSource>
        </ToolbarItem>
    </ContentPage.ToolbarItems>

Así mismo, agregamos las siguiente propiedades de:
  Image Source="ListUsers16.png"

Las demás propiedades tendrá el Binding para la referencia a los atributos de la entidad de datos.
  Label Text="{Binding email}" ...
  Label Text="{Binding name}" ...
  Label Text="{Binding password}" ...
  Image Source="{Binding image}" ...

XAML completo del archivo UsersList.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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="AppDIAbetes.Views.UsersList"
             Title="Usuarios Registrados">
    <ContentPage.ToolbarItems>
        <ToolbarItem Clicked="OnItemAdded">
            <ToolbarItem.IconImageSource>
                <OnPlatform x:TypeArguments="ImageSource">
                    <On Platform="Android" Value="AddUser24.png" />
                </OnPlatform>
            </ToolbarItem.IconImageSource>
        </ToolbarItem>
    </ContentPage.ToolbarItems>
   
    <ContentPage.Content>
        <AbsoluteLayout Margin="3,3,3,3">
            <ScrollView>
                <FlexLayout IsVisible="True" JustifyContent="SpaceEvenly" Direction="Column" AlignItems="Start">

                    <ListView x:Name="listUser" Margin="0" ItemSelected="OnListItemSelected">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <StackLayout Margin="2,2,2,2" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                                        <Image Source="ListUsers16.png" HorizontalOptions="Start"/>
                                        <Label Text="{Binding email}" VerticalTextAlignment="Center" WidthRequest="160" HorizontalOptions="StartAndExpand"/>
                                        <Label Text="{Binding name}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand"/>
                                        <Label Text="{Binding password}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand"/>
                                        <Image Source="{Binding image}" HorizontalOptions="CenterAndExpand"/>
                                    </StackLayout>
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </FlexLayout>
            </ScrollView>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

3. En el archivo UsersEdit.xaml agregaremos las propiedades de:
    Toda las propiedades de tipo Entry tendrá el Binding para la referencia  a datos.

    Image Source="LogoDIAbetes.jpg" ...
    Entry x:Name="entryEmail" ...
    Entry x:Name="entryName" ...
    Entry x:Name="entryPassword" ...
    Entry x:Name="entryConfPassword" ....
    Label x:Name="warningPassword" ...
    Entry x:Name="entryPhone" ...
    Label x:Name="warningPhone" ...
    Label Text="Activo" Etiqueta para el Switch
    Switch x:Name="valActive" Propiedad para validar la baja o alta del usuario
    Button x:Name="userEdit" Clicked="userEdit_Clicked" Botón para editar o actualiza usuario 
    Button x:Name="userDelete" Clicked="userDelete_Clicked" Botón para eliminar un usuario 
    
XAML completo del archivo UsersList.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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="AppDIAbetes.Views.UsersEdit" Title="{Binding name}">
    <ContentPage.ToolbarItems>
        <ToolbarItem Priority="1" />
    </ContentPage.ToolbarItems>
    <ContentPage.Content>
        <AbsoluteLayout Margin="5,0,5,5">
            <FlexLayout IsVisible="True" JustifyContent="SpaceEvenly" Direction="Column" AlignItems="Center" Margin="30,0,30,0" >
                <Image Source="LogoDIAbetes.jpg" HeightRequest="140" WidthRequest="140" FlexLayout.AlignSelf="Center" BackgroundColor="Transparent" />
                <Entry x:Name="entryEmail" Text="{Binding email}" Placeholder="Email" Keyboard="Email" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black" IsEnabled="False" />
                <Entry x:Name="entryName" Text="{Binding name}" Placeholder="Nombre" Keyboard="Text" MaxLength="10" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Entry x:Name="entryPassword" Text="{Binding password}" Placeholder="Contraseña" Keyboard="Text" MaxLength="12" IsPassword="True" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Entry x:Name="entryConfPassword" Text="{Binding password}" Placeholder="Confirmar Contraseña" MaxLength="12" IsPassword="True" FontSize="Small" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Label x:Name="warningPassword" Text="" IsVisible="False" TextColor="Blue" FontSize="12" BackgroundColor="Transparent" FlexLayout.AlignSelf="End"/>
                <Entry x:Name="entryPhone" Text="{Binding phone}" Placeholder="Celular" MaxLength="9" Keyboard="Telephone" FontSize="Small" FlexLayout.AlignSelf="Stretch" HorizontalOptions="CenterAndExpand" TextColor="Black"/>
                <Label x:Name="warningPhone" Text="" IsVisible="False" TextColor="Blue" FontSize="12" BackgroundColor="Transparent" FlexLayout.AlignSelf="End"/>
                <Label Text="Activo" FontSize="Small" FlexLayout.AlignSelf="Start"/>
                <Switch x:Name="valActive" IsToggled="{Binding active}" FlexLayout.AlignSelf="Start" />
                <Button x:Name="userEdit" Clicked="userEdit_Clicked" FontSize="Medium" TextColor="White" BorderColor="Black" BackgroundColor="#00b33c"  CornerRadius="5" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand" Text="Actualizar"></Button>
                <Button x:Name="userDelete" Clicked="userDelete_Clicked" FontSize="Medium" TextColor="White" BorderColor="Black" BackgroundColor="#FF0000"  CornerRadius="5" FlexLayout.AlignSelf="Stretch"  HorizontalOptions="CenterAndExpand" Text="Eliminar"></Button>
            </FlexLayout>
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage> 

Entidad Usuario (User):
Para comenzar abrimos el archivo o clase User.cs (equivalente a nuestro modelo de datos) y agregamos 2 nuevos atributos para determinar la alta o baja del usuario (active = true o false y image para mostrar la imagen en la lista como alta o baja):

using SQLite;

namespace AppDIAbetes.Models
{
    public class User
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string email { get; set; }
        public string name { get; set; }
        [MaxLength(12)]
        public string password { get; set; }
        [MaxLength(10)]
        public string phone { get; set; }
        public bool active { get; set; }
        public string image { get; set; }
    }
}

Métodos para manipular datos:
Ahora implementaremos los métodos equivalente a la manipulación de datos para la implementación del CRUD, para esto abrimos el archivo o clase UserDB.cs y creamos las siguientes instrucciones, considerando que se mantiene las instrucciones ya creadas, como la conexión a datos y el método login:

El método (C) SaveItem(User user) es el encargado de registras los datos de cada usuario.
El método (R) GetItemsAsync() es el encargado de obtener todos los datos registrados.
El método (U) UpdateItemAsync(User user) es el encargado de actualizar los datos de cada usuario.
El método (D) DeleteItemAsync(User user) es el encargado de eliminar un usuario.

El método valEmail(string strEmail) es el encargado de validar la existencia de un email, dicho método se invoca en el método SaveItem(User user), es decir antes de ingresar se pregunta si ya existe - en el caso que existe se retorna la letra E en todo caso se confirma la inserción de los datos con la letra I. 

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

namespace AppDIAbetes.Data
{
    public class UserDB
    {
        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 UserDB()
        {
            InitializeAsync().SafeFireAndForget(false);
        }

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

        #region metodos crud 
        public Task<List<User>> GetItemsAsync()
        {
            return Database.Table<User>().ToListAsync();
        }

        public Task<User> GetItemAsync(int id)
        {
            return Database.Table<User>().Where(i => i.Id == id).FirstOrDefaultAsync();
        }

        public string SaveItem(User user)
        {
            IEnumerable<User> result = valEmail(user.email);

            if (result.Count() == 0)
            {
                Database.InsertAsync(user);
                return "I";
            }
            else {
                return "E";
            }
        }

        public IEnumerable<User> valEmail(string strEmail)
        {
            var result = Database.QueryAsync<User>("Select * from User Where email=?", strEmail);
            return result.Result;
        }

        public Task<int> UpdateItemAsync(User user)
        {
            if (user.active == true)
            {
                user.image = "check16.png";
            }
            else
            {
                user.image = "delete16.png";
            }
            return Database.UpdateAsync(user);
        }

        public Task<int> DeleteItemAsync(User user)
        {
            return Database.DeleteAsync(user);
        }
        #endregion

        #region metodos login
        public IEnumerable<User> whereUser(string strEmail, string strPwd)
        {
            var result = Database.QueryAsync<User>("Select * from User Where email=? and password=?", strEmail, strPwd);

            return result.Result;
        }
        #endregion
    }
}

Para finalizar implementaremos el CodeBehind de cada interfaz:

1. En el CodeBehind SignUpLogin.xaml.cs agregaremos las siguientes instrucciones:
El método asíncrono signUp_Clicked(object sender, EventArgs e) es el encargado de invocar al método equivalente a la manipulación de datos SaveItem(User user) para el registro de los datos de cada usuario, previa validación de ingreso de cada propiedad de la pagina a la que corresponda.

El método listsignUp_Clicked(object sender, EventArgs e) es para invocar o ir a la pagina del listado de usuarios ya registrados.

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using AppDIAbetes.Models;
using AppDIAbetes.Data;
using System.Diagnostics;

namespace AppDIAbetes.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class SignUpLogin : ContentPage
    {
        User users = new User();
        UserDB userDB = new UserDB();

        public SignUpLogin()
        {
            InitializeComponent();
            entryEmail.ReturnCommand = new Command(() => entryName.Focus());
            entryName.ReturnCommand = new Command(() => entryPassword.Focus());
            entryPassword.ReturnCommand = new Command(() => entryConfPassword.Focus());
            entryConfPassword.ReturnCommand = new Command(() => entryPhone.Focus());
        }

        private async void signUp_Clicked(object sender, EventArgs e)
        {
            if (validateProperties() == "Of")
            {
                await DisplayAlert("Alerta", "Debe ingresar los datos solicitados.", "Aceptar");

            }
            else if (!string.Equals(entryPassword.Text, entryConfPassword.Text))
            {
                warningPassword.Text = "Ingresar la misma contraseña";
                entryPassword.Text = string.Empty;
                entryConfPassword.Text = string.Empty;
                warningPassword.TextColor = Color.IndianRed;
                warningPassword.IsVisible = true;
            }
            else if (entryPhone.Text.Length != 9)
            {
                warningPhone.Text = string.Empty;
                warningPhone.Text = "Ingresar 9 dígitos";
                warningPhone.TextColor = Color.IndianRed;
                warningPhone.IsVisible = true;
            }
            else {

                users.email = entryEmail.Text.Trim();
                users.name = entryName.Text.Trim();
                users.password = entryPassword.Text.Trim();
                users.phone = entryPhone.Text.Trim();
                users.active = true;//value for default in the insert
                users.image = "check16.png";

                try
                {

                    var returnResult = userDB.SaveItem(users);
                    if (returnResult == "I")
                    {
                        await DisplayAlert("Aviso", "Registro agregado exitosamente.", "Aceptar");
                        await Navigation.PushAsync(new UsersList());
                        cleanProperties();
                    }
                    else {
                        await DisplayAlert("Alerta", "El correo "+ users.email + " ya existe.", "Aceptar");
                    }
                }
                catch (Exception ex)
                {
                    await DisplayAlert("Error", ex.ToString(), "OK");
                    cleanProperties();
                }
            }
        }

        /// <summary>
        /// Limpia las propiedades después de ingresar los datos
        /// </summary>
        void cleanProperties()
        {
            entryEmail.Text = string.Empty;
            entryName.Text = string.Empty;

            entryPassword.Text = string.Empty;

            entryConfPassword.Text = string.Empty;
            warningPassword.Text = string.Empty;
            warningPassword.IsVisible = false;

            entryPhone.Text = string.Empty;
            warningPhone.Text = string.Empty;
            warningPhone.IsVisible = false;

        }

        /// <summary>
        /// Validación de cada propiedad
        /// </summary>
        /// <returns></returns>
        string validateProperties()
        {
            string result = null;
            if ((string.IsNullOrWhiteSpace(entryEmail.Text)) || (string.IsNullOrWhiteSpace(entryName.Text)) ||
                (string.IsNullOrWhiteSpace(entryPassword.Text)) || (string.IsNullOrWhiteSpace(entryPhone.Text)) ||
                (string.IsNullOrEmpty(entryPassword.Text)) || (string.IsNullOrEmpty(entryPhone.Text)) ||
                (string.IsNullOrEmpty(entryPassword.Text)) || (string.IsNullOrEmpty(entryPhone.Text)))
            {
                result = "Of";
            }
            else
            {
                result = "Ok";
            }
            return result;
        }

        private async void listsignUp_Clicked(object sender, EventArgs e) {
            await Navigation.PushAsync(new UsersList());
        }       
    }
}


2. En el CodeBehind UsersList.xaml.cs agregaremos las siguientes instrucciones:
Las explicaciones de cada método están como comentarios (/// Sección de color verde) al inicio de cada uno de ellos:

using AppDIAbetes.Data;
using AppDIAbetes.Models;
using System;
using System.Collections.Generic;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace AppDIAbetes.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class UsersList : ContentPage
    {
        UserDB userData = new UserDB();

        public UsersList()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Método para enlazar los datos con el ListView
        /// </summary>
        protected override async void OnAppearing()
        {
            base.OnAppearing();

            IList<User> users = await userData.GetItemsAsync();
            listUser.ItemsSource = users;
        }

        /// <summary>
        /// Método para invocar a la pagina de contenido de registrar nuevo usuario
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        async void OnItemAdded(object sender, EventArgs e)
        {
            await Navigation.PushAsync(new SignUpLogin
            {
                BindingContext = new User()
            });
        }

        /// <summary>
        /// Método encargado de seleccionar y vincular los datos con la pagina de contenido, para realizar la edición de datos - esto se logra a través del BindingContext.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        async void OnListItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            if (e.SelectedItem != null)
            {
                await Navigation.PushAsync(new UsersEdit
                {
                    BindingContext = e.SelectedItem as User
                });
            }
        }
    }

}

3. En el CodeBehind UsersEdit.xaml.cs agregaremos las siguientes instrucciones:
Del mismo modo, cada método cuenta con sus respectiva explicación al inicio y esta como comentario (/// Sección de color verde):

using AppDIAbetes.Data;
using AppDIAbetes.Models;
using System;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace AppDIAbetes.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class UsersEdit : ContentPage
    {
        User users = new User();
        UserDB userDB = new UserDB();
        public UsersEdit()
        {
            InitializeComponent();
        }
        /// <summary>
        /// Métodos para actualizar los datos de un usuario ya registrado
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void userEdit_Clicked(object sender, EventArgs e)
        {
            if (validateProperties() == "Of")
            {
                await DisplayAlert("Alerta", "Debe ingresar los datos solicitados.", "Aceptar");

            }
            else if (!string.Equals(entryPassword.Text, entryConfPassword.Text))
            {
                warningPassword.Text = "Ingresar la misma contraseña";
                entryPassword.Text = string.Empty;
                entryConfPassword.Text = string.Empty;
                warningPassword.TextColor = Color.IndianRed;
                warningPassword.IsVisible = true;
            }
            else if (entryPhone.Text.Length != 9)
            {
                warningPhone.Text = string.Empty;
                warningPhone.Text = "Ingresar 9 dígitos";
                warningPhone.TextColor = Color.IndianRed;
                warningPhone.IsVisible = true;
            }
            else
            {
                try
                {
                    //var users = (User)BindingContext;
                    users = (User)BindingContext;
                    await userDB.UpdateItemAsync(users);
                    await DisplayAlert("Aviso", "Registro actualizado exitosamente.", "Aceptar");
                    await Navigation.PushAsync(new UsersList());
                    cleanProperties();
                }
                catch (Exception ex)
                {
                    await DisplayAlert("Error", ex.ToString(), "OK");
                    cleanProperties();
                    //Debug.WriteLine(ex); ;
                }
            }                      
        }

        /// <summary>
        /// Métodos para eliminar un usuario ya registrado, se aplica la eliminación si el usuario confirma el mensaje
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void userDelete_Clicked(object sender, EventArgs e) {

            var result = await DisplayAlert("Confirmar", "Estas seguro de eliminar el registro", "Aceptar", "Cancelar");
            if (result)//True si se preciona Aceptar, y se elimina el registro.
            {
                users = (User)BindingContext;
                await userDB.DeleteItemAsync(users);
                await Navigation.PushAsync(new UsersList());
            }
            else
            {//False si se preciona Cancelar, y se cancela la elimación del registro.
                return;
            }
        }

        /// <summary>
        /// Limpia las propiedades después de actualizar los datos
        /// </summary>
        void cleanProperties()
        {
            entryEmail.Text = string.Empty;
            entryName.Text = string.Empty;

            entryPassword.Text = string.Empty;

            entryConfPassword.Text = string.Empty;
            warningPassword.Text = string.Empty;
            warningPassword.IsVisible = false;

            entryPhone.Text = string.Empty;
            warningPhone.Text = string.Empty;
            warningPhone.IsVisible = false;

        }

        /// <summary>
        /// Validación de cada propiedad, salvo la propiedad entryEmail que ya no permite ser modificado
        /// </summary>
        /// <returns></returns>
        string validateProperties()
        {
            string result = null;
            if ((string.IsNullOrWhiteSpace(entryPassword.Text)) || (string.IsNullOrWhiteSpace(entryPhone.Text)) ||
                (string.IsNullOrEmpty(entryPassword.Text)) || (string.IsNullOrEmpty(entryPhone.Text)) ||
                (string.IsNullOrEmpty(entryPassword.Text)) || (string.IsNullOrEmpty(entryPhone.Text)))
            {
                result = "Of";
            }
            else
            {
                result = "Ok";
            }
            return result;
        }
    }
}

Resultado:
Al finalizar la edición de esté post ya se cuenta con las siguiente interfaces desarrolladas:

     

     


Comparto el vídeo 📹 acerca de lo desarrollado de acuerdo a la descripción de este post publicado, todas las pruebas fueron validados en plataforma 📱 para Android.


Descarga la fuente de:
En proceso de carga...

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

Comentarios

Entradas más populares de este blog

Habilitar Usuario HR Oracle

Al realizar la primera instalación del Oracle, el usuario HR por defecto está bloqueado y por ende no podemos loguearnos como dicho usuario, lo que debe hacer son los siguiente pasos, aplicables para Linux o Windows.
1. Conectarse como usuario system o sysdba + contraseña haciendo uso del comando connect.
Usuario: system
Password: xxxx 


2. Hacer uso  del comando alter user hr account unlock desbloqueamos la cuenta.
alter user hr account unlock;

3. Escribimos el comando alter user HR identified by hr; con esto estamos diciendo que la contraseña será hr.

alter user HR identified by hr;

4. Ahora testeamos la conexión con el comando - conn hr/hr@xe. Si deseas después de conectarnos se puede realizar un select a la tabla employees del hr.


Resultado del select realizado
5. Con todos estos pasos realizados ya podemos logearnos desde cualquier IDE como el usuario hr  y la contraseña hr que definimos en el paso 3. 
Para finalizar nos loguearemos con el IDE Oracle SQL Developer.

Espero les sea de utilidad,…

Usuario SYS y SYSTEM - ORACLE

Usuario SYS y SYSTEM
Ambos usuario son creados de forma automática al crear la base de datos ORACLE y se otorga el rol de DBA.

SYS (password por defecto: CHANGE_ON_INSTALL).
SYSTEM (password por defecto: MANAGER).

Lo que se recomienda es cambiar el password de ambos usuarios por el tema de seguridad.

SYS:
Todas las tablas y vistas para el diccionario de datos de la base de datos están almacenados en el esquema SYS. Estas tablas y vistas son críticas para el funcionamiento de la base de datos ORACLE. Para mantener la integridad del diccionario de datos, las tablas del esquema SYS son manipulados solo por la base de datos. Nunca se debería modificar algo o crear tablas en el esquema del usuario SYS.

SYSTEM:
El usuario SYSTEM se utiliza para crear tablas y vistas adicionales que muestran información administrativa, tablas internas y vistas utilizado por varias opciones y herramientas de la base de datos ORACLE. No se recomienda utilizar el esquema SYSTEM para almacenar tablas de interés para usu…

Parámetro de entrada y salida – PL/SQL

Parámetro de entrada y salida – PL/SQL:
Los parámetros de entrada y salida no son los parámetros de inicialización de la base de datos ORACLE. Los parámetros de entra y salida son utilizados mayormente en implementaciones de funciones, procedimientos almacenados o bloques de código bajo el lenguaje del PL/SQL, se considera que ambos parámetros (entra y salida) puedan realizar operaciones en el mismo bloque PL/SQL, es decir, si enviamos un parámetro de entrada hará que cumpla cierta operación y retornara los valores de salida de dicha operación procesada de acuerdo al parámetro de ingresado. Es de acuerdo al caso que nos presenta en la implementación.
Algo importante al definir los parámetros, es saber y considerar cuántos tipos de parámetro existe si solo hablamos de entrada y salida, en realidad mi determinación seria 3 tipos:

Parámetros:

IN – entrada
OUT – salida
IN OUT – entrada salida

Parámetro IN – entrada:
El comportamiento común de estés tipos de parámetros es estar siempre pendiente d…