数据库更新时更新列表视图

Posted

技术标签:

【中文标题】数据库更新时更新列表视图【英文标题】:Updating listviews when db updates 【发布时间】:2021-12-17 07:58:35 【问题描述】:

我是 MVVM 的新手,在更新列表时遇到问题。

我有 2 个窗口和 ListViews。它们连接到属性“任务”。当我向我的数据库添加新行时,我需要刷新 ListViews。我已经完成了,但只针对 1 个窗口。

向数据库表添加新行

private void OnAddTaskExecuted(object p)
        
            tasks tsk = new tasks()
            
                taskname = "1",
                description = "",
                date = DateTime.Now,
                empID = 2
            ;
            Core.db.tasks.Add(tsk);
            Core.db.SaveChanges();
            Tasks = new ObservableCollection<tasks>(Core.db.tasks); 
            //it updates only in the window from which I'm adding the row
        

viewmodel ctor

public MainWindowViewModel()
        
            AddTask = new RelayCommand(OnAddTaskExecuted, p => true);
            Tasks = new ObservableCollection<tasks>(Core.db.tasks);
        

所以在单击 btn 后,我遇到了这种情况。 ListView 仅在我单击的窗口中更新,而在另一个窗口中不更新(新任务是第一个)img

附:我有 2 个相同的窗口,我只是通过 btn 单击创建一个新的相同窗口。那只是为了测试。我实际上正在创建一个包含大量页面的大型项目,并且我需要更新其中包含任务的每个集合。

【问题讨论】:

您是否在两个窗口中使用相同的视图模型? 是的,这就是我刚刚通过 btn click 重新打开它的同一个窗口 这不是我问的。我再试一次:您是否在两个窗口中使用相同的视图模型,即相同的实例? 嗯,明白了。那就是问题所在。我需要使用不同的实例 【参考方案1】:

您的问题是您有两个不同的 Window 实例和 ObservableCollection&lt;tasks&gt; Tasks 的单独实例

在 dotnet 中有多种方法可以持久地构造数据。以下是一些:

    假设两个 Windows 属于同一类型,最简单的方法是将 Tasks 设为静态字段。

    创建一个单独的类,例如。称为“TaskManager”,带有一个字段Tasks,并使用它。如果 TaskManager 是一个静态类,您不必费心组织任何实例。或者,还有像 Singletons 这样的概念。您还可以将您的数据或包含您的数据的对象存储在 App.xaml.cs 中,然后您可以通过Application.Current.SomeField 访问它

如果您想重用同一个 Window 实例而不是将数据存储在其他地方,这实际上取决于您导航到 Window 的方式。如果你用这样的东西打开你的窗口......

MyWindow window = new MyWindow();
window.Show();

...那么您必须如上所述以持久方式存储您的 WindowInstance,而不是每次要显示时都使用 new MyWindow() 实例化一个新的。

【讨论】:

好的,我正在使用静态类 TaskManager,但是我如何在其中使用 PropertyChanged。我将我的列表视图绑定到 Binding Source=x:Static mg:TaskManager.Tasks,当我更改静态字段时它不会更新。我假设我需要在获取字段时有一个 PropertyChanged,但我不能在我的静态类中使用 INotifyPropertyChanged。 对此有一些讨论,例如:Binding static property and implementing INotifyPropertyChanged 一种解决方案是使用任务管理器的视图模型上的非静态属性,您实际上将绑定到该属性。然后,当 setter 引发 PropertyChanged 时,所述属性的 getter 可以只指向静态属性。另一个链接:link 所以。我在 viewmodel 中有一个属性,我在其中使用 static class public static class TaskManager public static ObservableCollectionTasks; _viewmodel public ObservableCollection Tasks get => TaskManager._Tasks;设置 TaskManager._Tasks = 值; OnPropertyChanged(); 我做对了吗?因为我得到了同样的结果。我的列表视图仅在 1 个窗口中更新 您可能想为此打开一个单独的线程,其中包含所有详细信息。如果您的列表视图在 ViewModel 的完全不同实例中具有不同的值,则您可能仍在使用数据的不同副本 - 尽管没有看到代码,但无法说出原因。您发布的部分似乎大部分都是正确的(除了没有参数的 OnPropertyChanged - 但无论如何这里可能不需要 OnPropertyChanged。通常您毕竟不会直接设置此属性,而是 TaskManager 中的静态设置器。所以这个设置器可能甚至没有被调用)

以上是关于数据库更新时更新列表视图的主要内容,如果未能解决你的问题,请参考以下文章

Vue使用v-for显示列表时,数组里的item数据更新,视图中列表不同步更新的解决方法

删除项目后如何更新列表视图?

android - 在更改 EditText 值时无法更新列表视图

单击 CursorAdapter 中的按钮时如何在列表视图项目行中执行更新和删除操作

我正在使用 Getx 进行状态管理,当我将数据添加到服务器时,它不会在列表视图中出现更新的数据,直到热重启而列表视图位于 Obx 中

颤振:如何在不按按钮的情况下进行列表视图更新?