Aplicaciones 3
Aplicaciones 3
Maestría en Sistemas
Computacionales
Desarrollo de Aplicaciones para
Móviles
Ejercicios con .Net MAUI
Fecha: 25/02/2024
Actividad Integradora 6
Objetivo:
Desarrollar aplicaciones móviles utilizando .NET MAUI para cumplir con los siguientes
requerimientos:
Actividades
Donde nos damos cuenta de que nos pide un nombre de archivo, este es el nombre
del archivo a crear, y en el siguiente recuadro del formulario, nos pide el texto a
agregar, y con el botón de guardar texto, guardamos el archivo con el texto
ingresado.
Hacemos exactamente lo mismo para un segundo archivo, y después si queremos
recuperar el archivo guardado, solo basta con presionar el botón cargar texto, y
nuevamente nos mostrara lo siguiente:
Actividad Integradora 6
<ScrollView>
<StackLayout>
<Label Text="Nombre del archivo:" />
<Entry x:Name="fileNameEntry" Placeholder="Ingrese el nombre del
archivo" />
</StackLayout>
</ScrollView>
</ContentPage>
filePath =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationD
ata), fileName);
}
Actividad Integradora 6
Para este ejercicio vamos hacer una aplicación que muestre una ventana de
autentificación de usuario con su contraseña, posteriormente para la tercera
aplicación, daremos una funcionalidad.
<ScrollView>
<StackLayout Margin="20">
<Entry x:Name="UsernameEntry" Placeholder="Username" />
<Entry x:Name="PasswordEntry" Placeholder="Password"
IsPassword="True" />
<StackLayout Orientation="Horizontal">
<CheckBox x:Name="RememberMeCheckbox" VerticalOptions="Center" />
<Label Text="Remember Me" VerticalOptions="Center" />
</StackLayout>
</ContentPage>
public MainPage()
{
// Inicializamos los componentes, y definimos si hay algún nombre
// de entrada, para que este lo deje puesto.
InitializeComponent();
if (Preferences.Get(recuerdamekey, false))
{
UsernameEntry.Text = Preferences.Get(usuarioKey, string.Empty);
PasswordEntry.Text = Preferences.Get(PasswordKey, string.Empty);
RememberMeCheckbox.IsChecked = true;
}
}
Actividad Integradora 6
if (!string.IsNullOrWhiteSpace(username) && !
string.IsNullOrWhiteSpace(password))
{
if (rememberMe)
{
// Guardar los datos de autenticación en las preferencias
Preferences.Set(usuarioKey, username);
Preferences.Set(PasswordKey, password);
Preferences.Set(recuerdamekey, true);
}
else
{
// Si no se recuerdan los datos, eliminarlos de las preferencias
Preferences.Remove(usuarioKey);
Preferences.Remove(PasswordKey);
Preferences.Set(recuerdamekey, false);
}
En el ejercicio, aunque las pantallas tienen botones, en este caso ocupamos otro
ejemplo similar, ya que el ejercicio propuesto tenia muchos problemas, por lo que se
opto por recurrir en hacer uno nuevo, donde este incluye un solo botón de guardar, y
al dar click en los registros, este nos muestra un menú desplegable de editar o
eliminar.
<FlexLayout Direction="Column">
<VerticalStackLayout Padding="10" FlexLayout.Basis="400"
Background="Beige">
<Entry x:Name="nombreEntry" Placeholder="Nombre"/>
<Entry x:Name="direccionEntry" Placeholder="Dirección"/>
<Entry x:Name="telefonoEntry" Placeholder="Teléfono"/>
<Entry x:Name="correoEntry" Placeholder="Correo electrónico"/>
Actividad Integradora 6
<Button x:Name="GuardarButton" Text="Guardar"
Clicked="Guardar_Clicked"/>
</VerticalStackLayout>
<ListView x:Name="listView" FlexLayout.Grow="1" HasUnevenRows="True"
ItemTapped="listView_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<VerticalStackLayout Padding="5">
<Label Text="{Binding Nombre}" FontSize="17"
FontAttributes="Bold" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Column ="0" Text="{Binding Dirección}" />
<Label Grid.Column ="2" Text="{Binding Teléfono}" />
<Label Grid.Column ="3" Text="{Binding Correo }" />
</Grid>
</VerticalStackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</FlexLayout>
</ContentPage>
namespace agenda3
{
public partial class MainPage : ContentPage
{
private readonly LocalDbService _dbService;
private int _editCustomerId;
public MainPage(LocalDbService dbService)
{
InitializeComponent();
_dbService = dbService;
Task.Run(async () => listView.ItemsSource = await
_dbService.GetCustomers());
}
nombreEntry.Text = string.Empty;
direccionEntry.Text = string.Empty;
telefonoEntry.Text = string.Empty;
correoEntry.Text = string.Empty;
switch (action){
case "Edit":
_editCustomerId = customer.Id;
Actividad Integradora 6
nombreEntry.Text = customer.Nombre;
direccionEntry.Text = customer.Direccion;
telefonoEntry.Text = customer.Telefono;
correoEntry.Text = customer.CorreoElectronico;
break;
case "Delete":
await _dbService.Delete(customer);
listView.ItemsSource = await _dbService.GetCustomers();
break;
}
}
}
using Microsoft.Extensions.Logging;
namespace agenda3
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
builder.Services.AddSingleton<LocalDbService>();
builder.Services.AddTransient<MainPage>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
Actividad Integradora 6
}
}
using SQLite;
namespace agenda3
{
public class LocalDbService
{
private const string DB_NAME = "demo_local_db.db3";
private readonly SQLiteAsyncConnection _connection;
public LocalDbService()
{
_connection = new
SQLiteAsyncConnection(Path.Combine(FileSystem.AppDataDirectory, DB_NAME));
_connection.CreateTableAsync<Customer>();
}
public async Task<List<Customer>> GetCustomers()
{
return await _connection.Table<Customer>().ToListAsync();
}
}
}
using SQLite;
namespace agenda3
{
[Table("customer")]
public class Customer
{
[PrimaryKey]
[AutoIncrement]
[Column("id")]
public int Id { get; set; }
[Column("nombre")]
public string Nombre { get; set; }
[Column("direccion")]
public string Direccion { get; set; }
[Column("telefono")]
public string Telefono { get; set; }
[Column("correo")]
public string CorreoElectronico { get; set; }
}
}
De esta forma tenemos la aplicación con las funciones que se piden en el ejercicio.
using acceso1.Paginas;
namespace acceso1
{
public partial class MainPage : ContentPage
{
private const string recuerdamekey = "Recuerdame";
private const string usuarioKey = "Usuario";
private const string PasswordKey = "Password";
public MainPage()
{
// Inicializamos los componentes, y definimos si hay algún nombre
// de entrada, para que este lo deje puesto.
InitializeComponent();
if (Preferences.Get(recuerdamekey, false))
{
UsernameEntry.Text = Preferences.Get(usuarioKey, string.Empty);
PasswordEntry.Text = Preferences.Get(PasswordKey, string.Empty);
RememberMeCheckbox.IsChecked = true;
Actividad Integradora 6
}
if (user != null)
{
// Usuario encontrado, navegar a la página Pagina2
await Navigation.PushAsync(new Paginas.Pagina2(localDbService, user));
}
else
{
// Usuario no encontrado, mostrar mensaje de error
await DisplayAlert("Error", "Usuario no encontrado", "Aceptar");
}
}
}
Para el Reto, aún falta implementar más cosas para ir detallando el código, ya
que hay varias referencias de saltar de página en página, esto se va a ir
puliendo con el diseño más específico de la aplicación, e iniciando un
proyecto desde cero, para tomar en cuenta todas las características que tiene la
aplicación.
Referencias:
1. s/n [ El Camino Dev]. (15 jun 2022). Curso de .NET MAUI gratis # 2 -
Tipos de Páginas. [Video]. Recuperado de
https://www.youtube.com/watch?v=EXznxjxqN_g
2. s/n [Generar APK Firmado en NET MAUI]. (10 ago 2023). Generar APK
Firmado en NET MAUI. [Video]. Recuperado de
https://www.youtube.com/watch?v=1m3Wt9UTGvI&t=202s
Actividad Integradora 6
3. s/n [Coding Droplets]. (21 nov 2023). DotNet MAUI Sqlite Tutorial - .Net
MAUI Sqlite CRUD Operations. [Video]. Recuperado de
https://www.youtube.com/watch?v=VziMUc-VQko