在视图模型|MVVM之间共享数据
本文关键字:之间 共享 数据 MVVM 视图 模型 | 更新日期: 2023-09-27 18:19:26
你好,栈中的好人溢出。
编辑:源代码可用于:https://www.dropbox.com/sh/yq4qbznl4b6gm4h/AADdjd_hb-OQXV5KL8OU5cbqa?dl=0有关I4PRJ4-->后端-->后端.sln.的详细信息
我目前正在制作一个带有GUI的产品管理系统。我们已经决定使用MVVM,而且我们还在学习它。尽管我有个问题。在主屏幕上,会显示类别列表,并且还会显示所选类别中的产品。
到目前为止,我们已经将数据绑定到一个可观察的集合中。但是,当我们需要使用不同的视图和视图模型添加另一个产品时,问题就出现了。在这种情况下,我们需要有带数据的Categories。我们通过主窗口中的一个命令打开添加产品视图,因此要将数据传递到视图模型,我们必须将对象从MainWindowViewModel传递到AddProductView,然后传递到AddProductionViewModel——这不是我想要的耦合。
因此,我尝试使用singletonpattern,并将可观察集合绑定为:
xmlns:models="clr-namespace:Backend.Models"
..
..
<ListBox Margin="0, 30, 0, 0" ItemsSource="{Binding Source={x:Static models:GlobalCategories.CategoryList}, Path=Name}" DisplayMemberPath="Name"/>
其中GlobalCategories如下:
【型号:GlobalCategories】
public class GlobalCategories
{
private static BackendProductCategoryList _list;
public static BackendProductCategoryList CategoryList
{
get
{
if (_list == null)
{
MessageBox.Show("Made new list");
return new BackendProductCategoryList();
}
MessageBox.Show("Returned old list");
return _list;
}
set { _list = value; }
}
}
正如您在代码中看到的,会出现一个messagesbox,告诉我返回了什么。但使用上面的XAML代码,它实际上创建了那个对象,据我所知,它不会这么做,因此您必须自己初始化它。它实际上创建了对象,消息框会显示已经创建了一个新列表。
尽管如果我在MainWindowViewModel 中执行以下操作
public class MainWindowViewModel
{
public MainWindowViewModel()
{
MessageBox.Show("" + CategoryList.Count);
}
然后它会创建另一个列表,但如果我再做一个操作,我会收到一条"旧列表"消息。发生了什么事?为什么会发生这种事?我做错了什么?哦,绑定不起作用,当我这样做的时候,什么都没有显示。它把我逼疯了。我有C和C++的背景,已经使用C#和xaml几个月了——我需要控制。和指针:-D
我真的希望你们能在这里帮助我,让我了解发生了什么,以及我如何解决它
甚至更好——有更好的方式在视图模型之间共享数据吗?因为老实说,我不是singleton的最大粉丝,我真的会设想另一种在视图模型之间共享数据的方法。
非常感谢你的帮助!
致问候,
Benjamin
我认为您可能会对属性访问器的工作方式感到困惑。Set and get只允许您将看起来像常规属性的成员声明为引用它们的所有成员,但这些成员是用代码实现的。当某个东西需要访问列表时,它会调用getter,并期望该函数返回一个值(或null)。您当前的实现正在创建一个新列表并返回它:
return new BackendProductCategoryList();
但是您没有在_list中设置值,所以下次调用getter时,_list的值仍然为null,您可以再次创建并返回列表。等等。你所需要做的就是存储它,这样列表只创建一次:
public static BackendProductCategoryList CategoryList
{
get
{
if (_list == null)
{
MessageBox.Show("Made new list");
_list = new BackendProductCategoryList();
}
else
MessageBox.Show("Returned old list");
return _list;
}
set { _list = value; }
}
另外一个提示:不要在访问者中调用MessageBox.Show,你应该在访问者中尽可能少地做工作。由于许多原因,使用这样的静态方法也不是一个好主意,但我将把它留给另一个问题(查找"依赖注入")。