Maui学习笔记- SQLite简单使用案例

在本案例中我们将使用EFCore对象关系映射器,对SQLite数据库进行添加删除操作。我们将从数据库读取数据并显示在CollectionView中。并使用RefreshView实现下拉刷新数据。

 IOS下运行程序

 创建项目

首先需要安装NuGet包

  • Microsoft.EntityFrameworkCore.Sqlite

  • CommunityToolkit.Mvvm

  • CommunityToolkit.Maui(需要在MauiProgram内引入)

  • EFCore使用DbContext连接数据库并使用DbSet<>表示数据中的每个表。

创建用户表和数据模型

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
}
public class UserContext:DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        string daPath = Path.Combine(FileSystem.AppDataDirectory, "localdatabase.db");
        //EFCore支持不同的数据库,这里我们使用SQLite
        optionsBuilder.UseSqlite($"Filename={daPath}");
        
        base.OnConfiguring(optionsBuilder);
    }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
      //为数据库设置初始数据
        modelBuilder.Entity<User>().HasData(new User
        {
            Id = 1,
            Name = "张三",
            Email = "张三@163.com",
            Phone = "123456789"
        });
        
        base.OnModelCreating(modelBuilder);
    }
}
  • 在APP.xaml.cs中初始化数据库

public partial class App : Application
{
    public App()
    {
        SQLitePCL.Batteries_V2.Init();

        using (var context = new UserContext())
        {
            context.Database.EnsureCreated();
        }
        
        InitializeComponent();

        MainPage = new AppShell();
    }
}
  • 创建ViewModels目录并创建MainViewModel

  • 使用User类绑定到CollectionView,并使用Refreshing绑定到RefreshView元素。

  • LoadUserAsync用来刷新视图,加载数据。

public partial class MainViewModel:ObservableObject
{
    [ObservableProperty]
    ObservableCollection<User> users;

    [ObservableProperty] private bool refreshing;

  
    [RelayCommand]
    private async Task LoadUserAsync()
    {
        await Task.Run(() =>
        {
            using var context = new UserContext();

            Users = new ObservableCollection<User>(context.Users);
        });

        Refreshing = false;
    }

    [RelayCommand]
    void Showing()
    {
        Refreshing = true;
    }
  
  //删除用户
  [RelayCommand]
    private void DeleteUser(User user)
    {
        var context = new UserContext();

        context.Users.Remove(user);
        
        context.SaveChanges();
        
        Users.Remove(user);
    }

  //导航到用户编辑页面
    [RelayCommand]
    private async Task ShowNewFormAsync()
    {
        await Shell.Current.GoToAsync(nameof(UserEditPage),parameters:new Dictionary<string, object>
        {
            {"ParentRefreshAction",(Func<User,Task>)RefreshAddedAsync},
            {"Item",new User()}
        });
    }

}
  • 创建UserEditPage视图页面和UserEditViewModel

  • 在UserEditViewModel中我们要实现IQueryAttributable接口

  • ApplyQueryAttributes从查询参数中加载用户对象和刷新回调函数。 SaveAsync保存用户信息到数据库,并调用父页面的刷新操作,最后返回上一页。

public partial class UserEditViewModel:ObservableObject,IQueryAttributable
{
  //接受当前编辑的用户信息
    [ObservableProperty] private User itemUser;

  //用于在保存后刷新主页
   protected Func<User, Task> ParentRefreshAction { get;set; }

    [RelayCommand]
    private async Task SaveAsync()
    {
        await using var context = new UserContext();
        
        context.Users.Add(ItemUser);

        context.SaveChangesAsync();
        
        await ParentRefreshAction(ItemUser);
        
        await Shell.Current.GoToAsync("..");
    }
    
    public void ApplyQueryAttributes(IDictionary<string, object> query) {
        if (query.TryGetValue("Item", out object currentItem)) {
             ItemUser = (User)currentItem;
        }
        if (query.TryGetValue("ParentRefreshAction", out object parentRefreshAction)) {
            ParentRefreshAction = (Func<User, Task>)parentRefreshAction;
        }
        query.Clear();
    }
}
  • UserEditPage页面上的Entry用来接收用户信息。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:MauiApp3.ViewModels;assembly=MauiApp3"
             x:Class="MauiApp3.Views.UserEditPage"
             Title="新用户">
    <ContentPage.BindingContext>
        <vm:UserEditViewModel/>
    </ContentPage.BindingContext>
    
    <Grid>
        <VerticalStackLayout VerticalOptions="Start">
            <Entry Placeholder="用户名"
                   Text="{Binding ItemUser.Name}"/>
            <Entry Placeholder="电话"
                   Text="{Binding ItemUser.Phone}"/>
            <Entry Placeholder="Email"
                   Text="{Binding ItemUser.Email}"
                   ReturnCommand="{Binding SaveCommand}"/>
            <Button Text="保存" 
                    Command="{Binding SaveCommand}"/>
        </VerticalStackLayout>
        <ActivityIndicator 
            VerticalOptions="Center"
            HorizontalOptions="Center"
            IsRunning="{Binding SaveCommand.IsRunning}"/>
    </Grid>
</ContentPage>
  • 注册路由页面

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute(nameof(UserEditPage),typeof(UserEditPage));
    }
}
  • 主页代码

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:MauiApp3.ViewModels"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:models="clr-namespace:MauiApp3.Models"
             x:DataType="{x:Type vm:MainViewModel}"
             x:Class="MauiApp3.MainPage">
    <ContentPage.BindingContext>
        <vm:MainViewModel/>
    </ContentPage.BindingContext>
    <ContentPage.Behaviors>
        <toolkit:EventToCommandBehavior
            EventName="Appearing"
            Command="{Binding ShowingCommand}"/>
    </ContentPage.Behaviors>
    <ContentPage.Resources>
        <DataTemplate 
            x:Key="UserTemplate"
            x:DataType="models:User">
            <SwipeView>
                <SwipeView.RightItems>
                    <SwipeItem
                        Text="Delete"
                        BackgroundColor="IndianRed"
                        Command="{Binding Path=BindingContext.DeleteUserCommand,Source={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContentPage}}}"
                        CommandParameter="{Binding}"/>
                </SwipeView.RightItems>
            
            <Grid RowDefinitions="40,40"
                  ColumnDefinitions="*,*"
                  Padding="10">
                <Label
                    Text="{Binding Name}"/>
                <Label
                    Text="{Binding Phone}"
                    Grid.Column="1"/>
                <Label
                    Text="{Binding Email}"
                    TextColor="DarkGrey"
                    Grid.Row="1"
                    Grid.ColumnSpan="2"/>
                
            </Grid>
            </SwipeView>
        </DataTemplate>
    </ContentPage.Resources>
    <Grid>
        <RefreshView IsRefreshing="{Binding Refreshing}"
                     Command="{Binding LoadUsersCommand}">
            <CollectionView ItemsSource="{Binding Users}"
                            ItemTemplate="{StaticResource UserTemplate}"/>
        </RefreshView>
        
        <Button
            Text="+"
            Command="{Binding ShowNewFormCommand }"
            WidthRequest="56"
            HeightRequest="56"
            FontSize="24"
            HorizontalOptions="End"
            VerticalOptions="End"
            Margin="16"/>
    </Grid>
 

</ContentPage>

后续会对该案例添加一个用户详情页面,并改进优化一下代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值