在视图模型|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

在视图模型|MVVM之间共享数据

我认为您可能会对属性访问器的工作方式感到困惑。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,你应该在访问者中尽可能少地做工作。由于许多原因,使用这样的静态方法也不是一个好主意,但我将把它留给另一个问题(查找"依赖注入")。