UWP MVVM SQLite C#:ListView新增项需重载页面才可实现更新功能
根据你的描述,核心问题是新增项的属性变更没有正确打通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

