Tutoriel (BBCode) — Créer une appli .NET MAUI avec une base SQLite
Créer une application mobile avec .NET MAUI et une base de données SQLite » (exemple : gestionnaire de mots de passe).
Objectif
Créer une application .NET MAUI (Android/Windows/macOS/iOS) qui stocke des éléments dans une base SQLite locale via le package SQLite‑net‑PCL.
Prérequis
- Windows 10/11 ou macOS, avec les outils MAUI (Visual Studio 2022 + charge de travail .NET MAUI) et SDKs requis.
- .NET 8 (ou 7) installé.
- Notions de base en C# / XAML.
Références utiles
• Parcours Microsoft Learn .NET MAUI : Build apps with .NET MAUI
1) Créer le projet .NET MAUI
- Dans Visual Studio : Créer un nouveau projet → .NET MAUI App → nommez‑le MyPasswordManager. (Vous pouvez aussi utiliser la CLI :
.)Code:
dotnet new maui -n MyPasswordManager - Lancez l’appli « Hello World » pour valider l’environnement (Android Emulator/Windows).
2) Ajouter les packages NuGet SQLite
Installez dans le projet :
- SQLite‑net‑PCL — fournisseur ORM léger pour SQLite.
- SQLitePCLRaw.bundle_green — nécessaire sur certaines configs pour embarquer le moteur natif.
Astuce : installez d’abord SQLitePCLRaw.bundle_green, puis SQLite‑net‑PCL, afin d’éviter les erreurs de liaison natives selon la plateforme.
3) Modèle de données
Créez un dossier Models et ajoutez PasswordEntry.cs :
C#:
// Models/PasswordEntry.cs using SQLite;
namespace MyPasswordManager.Models { public class PasswordEntry { [PrimaryKey, AutoIncrement] public int Id { get; set; }
[MaxLength(200), NotNull]
public string Title { get; set; }
[MaxLength(200)]
public string Username { get; set; }
[MaxLength(200)]
public string Password { get; set; }
public string Notes { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
}
4) Service d’accès aux données (SQLite)
Créez un dossier Services et ajoutez DatabaseService.cs :
C#:
// Services/DatabaseService.cs using SQLite; using MyPasswordManager.Models;
namespace MyPasswordManager.Services { public class DatabaseService { private readonly SQLiteAsyncConnection _db;
public DatabaseService(string dbPath)
{
_db = new SQLiteAsyncConnection(dbPath);
}
public async Task InitAsync()
{
await _db.CreateTableAsync<PasswordEntry>();
}
public Task<List<PasswordEntry>> GetAllAsync() =>
_db.Table<PasswordEntry>().OrderByDescending(p => p.CreatedAt).ToListAsync();
public Task<PasswordEntry> GetAsync(int id) =>
_db.Table<PasswordEntry>().Where(p => p.Id == id).FirstOrDefaultAsync();
public async Task<int> SaveAsync(PasswordEntry entry)
{
if (entry.Id == 0)
return await _db.InsertAsync(entry);
else
return await _db.UpdateAsync(entry);
}
public Task<int> DeleteAsync(PasswordEntry entry) =>
_db.DeleteAsync(entry);
}
}
Chemin de base de données recommandé : Path.Combine(FileSystem.AppDataDirectory, "passwords.db3"), afin d’utiliser un répertoire local persistant et sandboxé pour l’app.
5) Enregistrement via l’injection de dépendances
Dans MauiProgram.cs :
C#:
// MauiProgram.cs using Microsoft.Maui.Storage; using MyPasswordManager.Services;
namespace MyPasswordManager;
public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); });
string dbPath = Path.Combine(FileSystem.AppDataDirectory, "passwords.db3");
builder.Services.AddSingleton(new DatabaseService(dbPath));
var app = builder.Build();
// Initialisation de la base (création des tables)
using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<DatabaseService>();
db.InitAsync().GetAwaiter().GetResult();
return app;
}
}
6) Pages & XAML — Liste + Édition
Page Liste : affiche les entrées et permet d’ajouter/supprimer.
Créez Pages/PasswordListPage.xaml :
XML:
// Pages/PasswordListPage.xaml
<CollectionView.ItemTemplate> <SwipeView.RightItems> </SwipeView.RightItems> </CollectionView.ItemTemplate>
Code‑behind PasswordListPage.xaml.cs :
C#:
// Pages/PasswordListPage.xaml.cs using MyPasswordManager.Models; using MyPasswordManager.Services;
namespace MyPasswordManager.Pages;
public partial class PasswordListPage : ContentPage { private readonly DatabaseService _db;
public PasswordListPage(DatabaseService db)
{
InitializeComponent();
_db = db;
BtnAdd.Clicked += async (_, __) =>
{
await Navigation.PushAsync(new PasswordEditPage(_db));
};
EntriesView.SelectionChanged += async (_, e) =>
{
if (e.CurrentSelection?.FirstOrDefault() is PasswordEntry item)
{
await Navigation.PushAsync(new PasswordEditPage(_db, item.Id));
EntriesView.SelectedItem = null;
}
};
// Après une suppression via Swipe, on recharge.
EntriesView.SwipeEnded += async (_, __) =>
{
await LoadAsync();
};
}
protected override async void OnAppearing()
{
base.OnAppearing();
await LoadAsync();
}
private async Task LoadAsync()
{
EntriesView.ItemsSource = await _db.GetAllAsync();
}
}
Page Édition : créer/modifier une entrée.
Pages/PasswordEditPage.xaml :
XML:
PasswordEditPage.xaml.cs :
C#:
using MyPasswordManager.Models; using MyPasswordManager.Services;
namespace MyPasswordManager.Pages;
public partial class PasswordEditPage : ContentPage { private readonly DatabaseService _db; private PasswordEntry _entry;
public PasswordEditPage(DatabaseService db, int id = 0)
{
InitializeComponent();
_db = db;
_ = InitAsync(id);
BtnSave.Clicked += async (_, __) =>
{
_entry.Title = TitleEntry.Text;
_entry.Username = UserEntry.Text;
_entry.Password = PassEntry.Text;
_entry.Notes = NotesEditor.Text;
await _db.SaveAsync(_entry);
await Navigation.PopAsync();
};
BtnDelete.Clicked += async (_, __) =>
{
if (_entry?.Id > 0)
{
await _db.DeleteAsync(_entry);
await Navigation.PopAsync();
}
};
}
private async Task InitAsync(int id)
{
_entry = (id == 0) ? new PasswordEntry() : await _db.GetAsync(id);
TitleEntry.Text = _entry.Title;
UserEntry.Text = _entry.Username;
PassEntry.Text = _entry.Password;
NotesEditor.Text = _entry.Notes;
}
}
7) Navigation par défaut
Remplacez la page de démarrage par une navigation vers la liste :
C#:
// App.xaml.cs using MyPasswordManager.Pages;
public partial class App : Application { public App(PasswordListPage listPage) { InitializeComponent(); MainPage = new NavigationPage(listPage); } }
C#:
builder.Services.AddTransient<Pages.PasswordListPage>();
8) Exécuter et tester
- Démarrez sur l’émulateur Android ou Windows. Ajoutez/éditez/supprimez des entrées ; elles sont persistées dans AppDataDirectory via SQLite.
9) Sécurité (important)
Cette démo stocke des mots de passe en clair pour l’apprentissage. Pour une application réelle, envisagez :
- Chiffrer les champs sensibles (librairie de chiffrement côté client).
- Utiliser SecureStorage pour des secrets/cookies plutôt que SQLite quand c’est possible.
- Masquer/afficher le mot de passe à la demande, activer le copier‑coller avec prudence, etc.
10) Annexes — Prompts Copilot Chat (VS Code)
Même si le développement MAUI se fait surtout dans Visual Studio, vous pouvez rédiger vos classes/VM/XAML dans VS Code et utiliser Copilot Chat pour générer/compléter du code C# et XAML.
Exemples de questions à poser à Copilot Chat
- Modèle + attributs SQLite
Vous : « Écris une classe C# PasswordEntry pour SQLite‑net‑PCL avec Id auto‑incrémenté, Title, Username, Password, Notes, CreatedAt. »
Copilot : Génère la classe avec les attributs. - Service CRUD asynchrone
Vous : « Crée un service DatabaseService basé sur SQLiteAsyncConnection avec InitAsync, GetAllAsync, GetAsync, SaveAsync, DeleteAsync. »
Copilot : Propose une implémentation testable. - Page XAML liste + Swipe pour supprimer
Vous : « Donne un XAML MAUI avec CollectionView et SwipeView pour supprimer un item. » - Refactor DI & Navigation
Vous : « Montre comment enregistrer DatabaseService en Singleton et PasswordListPage en Transient, puis définir MainPage = NavigationPage. »
11) Dépannage rapide
- Erreur native SQLite non trouvée → vérifiez l’installation de SQLitePCLRaw.bundle_green.
- Build Android échoue → confirmez la charge de travail MAUI/Android et les SDKs dans Visual Studio Installer.
- Appli « Hello World » ok mais XAML ne s’affiche pas → contrôlez la MainPage et la navigation.
Aller plus loin
- Parcours Microsoft Learn (.NET MAUI UI, XAML, data binding, navigation, stockage local).