在maui项目中使用sqlite数据库,先在Nuget中搜索sqlite-net-pcl安装 ,再在搜索中输入sqlite空格green,搜索安装sqlitepclraw.bundle_green,如果不安装后者,将会报错。
在maui中体验一下sqlite,设计一个简单的笔记本simpleNotes,先建模型,在文件夹models中创建Note.cs。
using SQLite;
namespace SimpleNotes.Models
{
public class Note
{
[PrimaryKey,AutoIncrement]
public int NoteId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime CreationTime { get; set; }
public DateTime LastModifiedTime { get; set; }
}
}
在models文件夹中再建一个常量类,方便使用,文件名constants.cs。
namespace SimpleNotes.Models
{
public class Constants
{
private const string DBName = "notes.db3";
public const SQLite.SQLiteOpenFlags Flags = SQLite.SQLiteOpenFlags.Create |
SQLite.SQLiteOpenFlags.ReadWrite | SQLite.SQLiteOpenFlags.SharedCache;
public static string DatabasePath => Path.Combine(FileSystem.AppDataDirectory, DBName);
}
}
再在services文件夹建一个DatabaseService.cs,使用sqlite数据库的类。
using SimpleNotes.Models;
using SQLite;
namespace SimpleNotes.Services
{
public class DatabaseService
{
SQLiteAsyncConnection conn;
async Task Init()
{
if (conn is null)
{
conn = new SQLiteAsyncConnection(Constants.DatabasePath, Models.Constants.Flags);
await conn.CreateTableAsync();
}
}
public async Task> GetAll()
{
await Init();
return await conn.Table().ToListAsync();
}
public async Task GetNote(Note note)
{
await Init();
var local = note;
if (local is not null)
{
return await conn.Table().Where(n => n.NoteId == local.NoteId).FirstOrDefaultAsync();
}
return null;
}
public async Task AddNoteAsync(Note note)
{
await Init();
var local = note;
if (local is not null)
{
if (local.NoteId == 0)
{
local.CreationTime = DateTime.Now;
local.LastModifiedTime = DateTime.Now;
return await conn.InsertAsync(local);
}
else
{
local.LastModifiedTime = DateTime.Now;
return await conn.UpdateAsync(local);
}
}
return -1;
}
public async Task DeleteNoteAsync(Note note)
{
await Init();
var local = note;
if(local is not null)
{
var matchedNote = conn.Table().Where(n => n.NoteId == local.NoteId).FirstOrDefaultAsync();
if(matchedNote is not null)
{
return await conn.DeleteAsync(local);
}
}
return 0;
}
}
}
使用maui,不安装社区工具是不行的,真的是太方便了,提高效率,用nuget搜索安装communitytoolkit.maui和communitytoolkit.mvvm。
在viewmodels文件夹中创建AboutPageViewModel.cs。
namespace SimpleNotes.ViewModels
{
public class AboutPageViewModel
{
public static string AppName => $"程序名称:{AppInfo.Name}";
public static string Vertion => $"版本:{AppInfo.VersionString}";
public static string MoreMessage => $"使用MAUI架构,C#语言,xaml设计界面,使用IOC容器技术。";
}
}
在viewmodels文件夹中创建NotePageViewModel.cs。
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using SimpleNotes.Models;
using SimpleNotes.Services;
namespace SimpleNotes.ViewModels
{
public class NotePageViewModel : ObservableObject, IQueryAttributable
{
DatabaseService db;
Note _note = new Note();
public NotePageViewModel(DatabaseService databaseService)
{
db = databaseService;
AddNoteCommand = new AsyncRelayCommand(AddNote);
DeleteNoteCommand = new AsyncRelayCommand(DeleteNote);
}
public void ApplyQueryAttributes(IDictionary query)
{
if (query.ContainsKey("load"))
{
Note local = query["load"] as Note;
_note = local;
OnRefresh();
}
else if (query.ContainsKey("name"))
{
var name = query["name"] as string;
if (name == "new")
{
_note = new Note();
OnRefresh();
}
}
}
private void OnRefresh()
{
OnPropertyChanged(nameof(Title));
OnPropertyChanged(nameof(Content));
OnPropertyChanged(nameof(CreationTime));
OnPropertyChanged(nameof(LastModifiedTime));
}
public string Title
{
get => _note.Title;
set => SetProperty(_note.Title, value, _note, (n, v) => n.Title = v);
}
public string Content
{
get => _note.Content;
set => SetProperty(_note.Content, value, _note, (n, v) => n.Content = v);
}
public DateTime CreationTime
{
get => _note.CreationTime;
set => SetProperty(_note.CreationTime, value, _note, (n, v) => n.CreationTime = v);
}
public DateTime LastModifiedTime
{
get => _note.LastModifiedTime;
set => SetProperty(_note.LastModifiedTime, value, _note, (n, v) => n.LastModifiedTime = v);
}
async Task AddNote()
{
await db.AddNoteAsync(_note);
await Shell.Current.GoToAsync("..");
}
public IAsyncRelayCommand AddNoteCommand { get; private set; }
async Task DeleteNote()
{
await db.DeleteNoteAsync(_note);
await Shell.Current.GoToAsync("..");
}
public IAsyncRelayCommand DeleteNoteCommand { get; private set; }
}
}
再在viewmodels文件夹下创建主页面MainPageViewModels.cs。
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using SimpleNotes.Models;
using SimpleNotes.Services;
using SimpleNotes.Views;
using System.Collections.ObjectModel;
namespace SimpleNotes.ViewModels
{
public class MainPageViewModel : ObservableObject
{
ObservableCollection notes;
DatabaseService db;
public ObservableCollection Notes
{
get => notes ??= new ObservableCollection();
set => SetProperty(ref notes, value);
}
public MainPageViewModel(DatabaseService databaseService)
{
db = databaseService;
InitializeCollectionCommand = new AsyncRelayCommand(InitializeCollection);
SelectedNoteCommand = new AsyncRelayCommand(SelectedNote);
NewNoteCommand = new AsyncRelayCommand(NewNote);
}
async Task InitializeCollection()
{
Notes.Clear();
foreach (Note note in await db.GetAll())
{
Notes.Add(note);
}
}
public IAsyncRelayCommand InitializeCollectionCommand { get; private set; }
async Task SelectedNote(Note note)
{
if (note is not null)
{
var parameter = new Dictionary()
{
{"load",note }
};
await Shell.Current.GoToAsync($"{nameof(NotePage)}", parameter);
}
}
public IAsyncRelayCommand SelectedNoteCommand { get; private set; }
async Task NewNote()
{
string name = "new";
await Shell.Current.GoToAsync($"{nameof(NotePage)}?name={name}");
}
public IAsyncRelayCommand NewNoteCommand { get; private set; }
}
}
再在views文件夹下创建AboutPage.xaml界面文件。
在views文件夹下创建NotePage.xaml界面文件。
在views文件夹下创建MainPage.xaml界面文件。
修改AppShell.xaml文件。
再修改mauiProgram.cs文件,由于maui自带容器,我们可以用用,最好用的是它的扩展builder.Services.AddSingleton
using CommunityToolkit.Maui;
using Microsoft.Extensions.Logging;
using SimpleNotes.Services;
using SimpleNotes.ViewModels;
using SimpleNotes.Views;
namespace SimpleNotes;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
//注册service,viewmodels views;
builder.Services.AddSingleton();
builder.Services.AddSingleton();
builder.Services.AddSingletonWithShellRoute($"{nameof(NotePage)}");
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
修改NotePage.xaml.cs文件,由于我们在容器中注册了,所以可以在构造函数中直接引用注册的类型。
using SimpleNotes.ViewModels;
namespace SimpleNotes.Views;
public partial class NotePage : ContentPage
{
public NotePage(NotePageViewModel viewmodel)
{
InitializeComponent();
BindingContext = viewmodel;
}
}
再修改MainPage.xaml.cs文件。
using SimpleNotes.ViewModels;
namespace SimpleNotes.Views;
public partial class MainPage : ContentPage
{
public MainPage(MainPageViewModel viewmodel)
{
InitializeComponent();
BindingContext = viewmodel;
}
private void MainPage_Appearing(object sender, EventArgs e)
{
((MainPageViewModel)BindingContext).InitializeCollectionCommand.Execute(null);
}
private void MainPage_NavigatedTo(object sender, NavigatedToEventArgs e)
{
notesCollection.SelectedItem = null;
}
}
在maui页面间传递自定义的值是这样写,使用shell.current.GogoAsync的第二个签名。
var parameter = new Dictionary()
{
{"load",note }
};
await Shell.Current.GoToAsync($"{nameof(NotePage)}", parameter);
第一个签名是这样写,自定义的只能用第二个。
string name = "new";
await Shell.Current.GoToAsync($"{nameof(NotePage)}?name={name}");
看看运行效果,达到预期。