Start Debugging

Una app de notas "solo local" en WinUI 3 es el tipo correcto de aburrida: offline-first, SQLite, primero el teclado

Miyanyedi Quick Note es una app de notas en WinUI 3 + SQLite que es offline-first y respetuosa con la privacidad. Aquí va por qué solo local es una característica, más un snippet mínimo de SQLite para apps de escritorio en .NET 8.

Otra app de escritorio “pequeña pero real” apareció hoy en r/csharp: Miyanyedi Quick Note, una herramienta ligera de notas construida con WinUI 3 y SQLite, diseñada explícitamente para ser offline-first y respetuosa con la privacidad.

Fuente: el post original y la ficha en Microsoft Store: hilo en r/csharp y página de la app en Microsoft Store.

”Solo local” es una característica, no un checkbox que falta

La mayoría de las apps de notas terminan en un sistema de cuentas porque la sincronización es palanca de crecimiento. El compromiso es obvio: más superficie, más caídas, más “¿dónde están mis datos?”.

Para una utilidad de escritorio Windows, “sin cloud” puede ser el producto:

Si construyes herramientas internas sobre .NET 8 (o incluso .NET 9), esta mentalidad de “offline-first por defecto” es una buena base.

SQLite encaja con apps WinUI 3 porque mantiene el dominio pequeño

SQLite no es “una elección de base de datos”, es una elección de alcance. Estás diciendo:

Eso encaja bien con los requisitos de UI de WinUI 3: puedes mantener el CRUD fuera del hilo de UI, actualizar la lista rápido y no tocar nunca un servidor.

Aquí va un snippet mínimo de “insertar nota y listar las últimas” usando Microsoft.Data.Sqlite que funciona en cualquier app de escritorio en .NET 8:

using Microsoft.Data.Sqlite;

static async Task AddNoteAsync(string dbPath, string text, CancellationToken ct)
{
    await using var conn = new SqliteConnection($"Data Source={dbPath}");
    await conn.OpenAsync(ct);

    var cmd = conn.CreateCommand();
    cmd.CommandText = """
        INSERT INTO notes(text, created_utc)
        VALUES ($text, $createdUtc);
        """;
    cmd.Parameters.AddWithValue("$text", text);
    cmd.Parameters.AddWithValue("$createdUtc", DateTimeOffset.UtcNow.ToString("O"));
    await cmd.ExecuteNonQueryAsync(ct);
}

static async Task<List<string>> ListLatestAsync(string dbPath, int take, CancellationToken ct)
{
    await using var conn = new SqliteConnection($"Data Source={dbPath}");
    await conn.OpenAsync(ct);

    var cmd = conn.CreateCommand();
    cmd.CommandText = """
        SELECT text
        FROM notes
        ORDER BY created_utc DESC
        LIMIT $take;
        """;
    cmd.Parameters.AddWithValue("$take", take);

    var results = new List<string>();
    await using var reader = await cmd.ExecuteReaderAsync(ct);
    while (await reader.ReadAsync(ct))
        results.Add(reader.GetString(0));

    return results;
}

El resto es UI: enlazar una lista, manejar Enter para guardar, Esc para enfocar y mantener las interacciones rápidas.

Si quieres un ejemplo para revisar la cordura de tus propias decisiones de UI con Windows App SDK, apps como esta son más útiles que repos de muestra gigantes. Son lo suficientemente pequeñas para copiar y lo suficientemente reales para revelar las partes complicadas.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Volver