我目前正在做一个项目,为了简化解释,假设在一个 TabControl 中有两个选项卡...
在一个选项卡中,您可以将文件夹添加到列表框。
在另一个选项卡中,有一个列表框显示您添加的所有文件夹中的所有项目。
每个选项卡都是一个 ViewModel(这是为了简化代码,因为将所有代码转储到一个 ViewModel 中会使其难以阅读和理解)。
为了让这个程序工作,两个 ViewModel 都需要访问项目列表:一个因为它必须显示它们,另一个因为它必须添加到它们。
我不知道该怎么做。我最初认为共享数据不好,一开始就不应该发生这种情况,但后来我意识到我想不出任何其他方法来做到这一点。
我是 MVVM 的新手(这是我使用 MVVM 的第一个真正的应用程序)并且最初开始使用它,因为我无法在类之间访问数据,并且认为 MVVM 会以某种方式解决这个问题,但我又来了。
如果有人能告诉我如何做到这一点,并可能用示例代码进行解释,我将不胜感激。我也乐于接受对我的方法的建议和建设性批评。
最佳答案
首先,您应该了解 MVVM 中的View 是什么。把它看成一个面板。可以嵌入 Window、TabControl 甚至 ListBox 项中的面板。还可以包含子面板的面板。基本上,如果您的应用程序不仅仅是一个简单的输入表单,那么它很可能会有多个View。不要试图将所有内容都放在一个 View/ViewModel 中,因为这会使以后的事情变得非常复杂。您希望拥有所谓的 View 层次结构 及其相应的ViewModels。会有很多 Views/ViewModels 但它们相对简单且易于维护(这里是使用 PRISM 在 View 之间切换的小示例,但您可以获得主要的想法 https://youtu.be/ZfBy2nfykqY?t=45m34s )。
Each tab is a ViewModel (this is to simplify code, as dumping all the code in one ViewModel makes it hard to read and understand).
这是正确的做法。下面是一些伪代码,描述了您的示例应用程序方案应该是什么样子:
// MODEL:
public class Model
{
ObservableCollection<Item> ListOfItems;
}
public class Item
{
}
// VIEWMODELS:
public class MainWindowViewModel
{
Model Model { get; set; }
Tab1ViewModel Tab1ViewModel { get; set; }
Tab2ViewModel Tab2ViewModel { get; set; }
public MainWindowViewModel()
{
Model = new Model();
Tab1ViewModel = new Tab1ViewModel(Model);
Tab2ViewModel = new Tab2ViewModel(Model);
}
}
public class Tab1ViewModel
{
ObservableCollection<ItemViewModel> ItemViewModels { get; set; } // Bind it to ListBox's ItemsSource
public Tab1ViewModel(Model m)
{
ItemViewModels = new ObservableCollection<ItemViewModel>();
// Populate ItemViewModels and keep it in sync with ListOfItems model by subscribing to its CollectionChanged event.
}
}
public class Tab2ViewModel
{
ObservableCollection<ItemViewModel> ItemViewModels { get; set; } // Bind it to ListBox's ItemsSource
public Tab2ViewModel(Model m)
{
ItemViewModels = new ObservableCollection<ItemViewModel>();
// Populate ItemViewModels and keep it in sync with ListOfItems model by subscribing to its CollectionChanged event.
}
}
public class ItemViewModel
{
Item Item { get; set; } // Model
public ItemViewModel(Item item)
{
Item = item;
}
}
现在您可以在不同的 View 中显示相同的数据并对其执行不同的操作。每个 View 都会自动更新,因为它引用相同的模型。
您还可以使用 EventAggregator 或类似的东西在 ViewModels 之间进行通信。
尽量避免使用可以从应用程序中的任何位置访问的数据的静态类/单例,因为这违反了封装原则。
关于c# - 如何在 ViewModel 之间访问数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43021314/