You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP MVVM SQLite C#:ListView新增项需重载页面才可实现更新功能

解决ListView新增项无法触发CRUD更新的问题

根据你的描述,核心问题是新增项的属性变更没有正确打通UI→ViewModel→数据库的通知链路,而原有项因为加载时已经建立了完整的绑定逻辑,所以能正常工作。下面分几个关键排查点和解决方案:

1. 确保实体类严格实现INotifyPropertyChanged接口

这是MVVM模式下属性变更通知的核心基础。你提到原有项能正常编辑同步,说明你大概率已经为实体类实现了这个接口,但要确认新增的实体实例也完全遵循这个实现——别图省事在新增时创建一个没有属性变更通知的简化版实体。

示例标准实现:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Collections.Generic;

public class YourEntity : INotifyPropertyChanged
{
    private int _id;
    private string _entityName;

    public int Id
    {
        get => _id;
        set => SetField(ref _id, value);
    }

    public string EntityName
    {
        get => _entityName;
        set => SetField(ref _entityName, value);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

注意:所有需要绑定到UI的属性,必须通过SetField方法赋值,确保每次属性变更都能触发PropertyChanged事件

2. 确认ViewModel的集合是ObservableCollection<T>而非List<T>

ObservableCollection会自动向UI发送集合增减的通知,而普通List<T>没有这个能力。如果你的ViewModel用的是List<T>,即使新增项后UI可能暂时显示,后续的属性变更通知也会直接失效。

ViewModel中集合的正确声明方式:

using System.Collections.ObjectModel;

public class YourViewModel : INotifyPropertyChanged
{
    // 推荐只读初始化,避免后续重新赋值破坏原有绑定
    public ObservableCollection<YourEntity> EntityItems { get; } = new ObservableCollection<YourEntity>();

    // 新增项的示例方法
    public void AddNewEntity(YourEntity newEntity)
    {
        // 第一步:将新增项写入SQLite数据库
        using var dbConn = new SqliteConnection("YourConnectionString");
        dbConn.Open();
        var insertCmd = dbConn.CreateCommand();
        insertCmd.CommandText = "INSERT INTO YourEntities (EntityName) VALUES (@Name); SELECT last_insert_rowid();";
        insertCmd.Parameters.AddWithValue("@Name", newEntity.EntityName);
        // 取回自增ID并赋值给实体(如果你的表用了自增主键)
        newEntity.Id = Convert.ToInt32(insertCmd.ExecuteScalar());

        // 第二步:将实体添加到ObservableCollection,UI会自动更新
        EntityItems.Add(newEntity);
    }

    // ... 实现ViewModel自身的INotifyPropertyChanged接口(如果有其他需要通知的属性)
}

关键:新增项时必须用EntityItems.Add(newEntity),绝对不要重新赋值EntityItems = new ObservableCollection<...>,否则会直接断开UI与原有集合的绑定

3. 检查UI绑定的Mode和UpdateSourceTrigger

确保ListView的ItemTemplate中,编辑控件的绑定设置了正确的触发时机——比如文本框应该在输入时立即更新数据源,而不是等到失去焦点:

<ListView ItemsSource="{Binding EntityItems}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBox Text="{Binding EntityName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200"/>
                <Button Content="保存" Command="{Binding DataContext.SaveCommand, RelativeSource={RelativeSource AncestorType=ListView}}"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Mode=TwoWay确保UI变更能同步回ViewModel,UpdateSourceTrigger=PropertyChanged确保输入内容实时更新数据源,避免延迟导致的不同步

4. 确认数据库操作后的实体状态一致性

当你把新增项写入数据库后,要保证ViewModel中的实体实例与数据库记录完全匹配——比如自增ID的赋值。如果漏掉这一步,后续编辑时可能无法正确定位到数据库中的对应记录,导致同步失效。

内容的提问来源于stack exchange,提问作者MikeJP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:18:11