在viewmodels之间共享数据| MVVM

时间:2015-10-27 21:15:09

标签: c# wpf xaml mvvm singleton

你好,堆栈的好人溢出

编辑:源代码可用于: https://www.dropbox.com/sh/yq4qbznl4b6gm4h/AADdjd_hb-OQXV5KL8OU5cbqa?dl=0 更多关于I4PRJ4的特色 - >后端 - > Backend.sln。

我目前正在制作一个具有GUI的产品管理系统。我们决定使用MVVM,我们还在学习它。 虽然我有问题。在主屏幕上,将显示类别列表,并且还会显示所选类别中的产品。

就目前而言,我们已将数据绑定到可观察的集合中。但是当我们需要使用不同的视图和视图模型添加另一个产品时,问题就出现了。在这种情况下,我们需要包含数据的类别。我们通过主窗口中的命令打开add-product-view,因此要将数据传递给viewmodel,我们必须将对象从MainWindowViewModel传递给AddProductView然后传递给AddProductViewModel - 这不是我想要的耦合。

所以我尝试使用singletonpattern,并将其绑定到observable集合:

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如下:

[Models: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; }
    }
}

正如您在代码中看到的那样,会出现一个消息框,告诉我返回了什么。但是使用上面的XAML代码,它实际上创建了该对象,这是我的理解,它不会那样做,因此你必须自己初始化它。它实际上创建了对象,而msgbox会说已经创建了一个新列表。

但是,如果我在MainWindowViewModel中执行以下操作

  public class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        MessageBox.Show("" + CategoryList.Count);
    }

然后它会创建另一个列表,但是如果我再进行另一个操作,我会得到一个“旧列表”消息。发生了什么 - 为什么会发生这种情况? 我究竟做错了什么?哦 - 并且绑定不起作用,当我这样做时没有显示任何内容。这让我疯了。我是从C和C ++的背景下来的,并且使用c#和xaml工作了几个月 - 我需要控制。和指南:-D

我真的希望你们能在这里帮助我,让我了解正在发生的事情,以及我如何解决它。

甚至更好 - 是否有更好的方法在视图模型之间共享数据?因为老实说,那么我不是单身人士的最大粉丝,并且会真正熟悉另一个在视图模型之间共享数据的解决方案。

非常感谢你的帮助!

致以最诚挚的问候,

本杰明

1 个答案:

答案 0 :(得分:0)

我认为关于财产访问者如何运作可能会有一些混乱。设置并获取简单地允许您将引用类似于常规属性的成员声明为引用它们但通过代码实现的所有内容。当某些东西需要访问列表时,它会调用你的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,你应该尽可能少地访问访问器。使用像这样的静态因素并不是一个好主意,但是我会将其留给另一个问题(查找&#34;依赖注入&#34;)。