【问题标题】: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 重新打开它的同一个窗口
  • 这不是我问的。我再试一次:您是否在两个窗口中使用相同的视图模型,即相同的实例?
  • 嗯,明白了。那就是问题所在。我需要使用不同的实例

标签: c# wpf entity-framework mvvm


【解决方案1】:

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

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

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

  2. 创建一个单独的类,例如。称为“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 中的静态设置器。所以这个设置器可能甚至没有被调用)
猜你喜欢
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 2021-01-13
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
相关资源
最近更新 更多