0

我有一个加载了 ProductList 的 View / ViewModel。此列表在屏幕上不可见。

我需要做的是显示一个新的视图/视图模型(例如 SelectProductView / SelectProductViewModel),将 ProductList 传递给它们,在用户选择特定产品后,关闭此视图并使用所选产品。

实现这一目标的最佳方法是什么?

我正在使用 MVVMLight,但我想这些想法不应该仅限于此。最简单的方法是创建一个视图,并将集合传递给它,但这听起来对 MVVM 不友好。我正在考虑从第一个 ViewModel 创建一个 SelectProductViewModel 并将集合传递给它,但我不知道如何自动创建 SelectProductView 并将其绑定到创建的 SelectProductViewModel。

编辑:在我的应用程序视图结构中有点复杂。我有一个主视图,它基本上需要托管一个 SelectProductView,因为这个视图必须覆盖整个屏幕。MainView 包含许多子视图和孙视图(通过选项卡),因此可能有 3 个不同的子视图或大子视图可以发出选择产品的请求。此外,某些视图不会预加载产品,因此该任务可能应该传播到 SelectProductViewModel。

结构示例:

                              MainView
                        /                   \
         ChildViewA                                   ChildViewB
            /  \                                       /     \
GrandChildViewA1 GrandChildViewA2            GrandChildViewB1 GrandChildViewB2

因此,GrandChildViewA1、ChildViewB 和 GrandChildViewB2 可以发出选择产品的请求。只有发出请求的视图才能获得选择的产品,其他人不应理会它。GrandChildViewA1 将在其中加载产品,但 GrandChildViewB2 不会在其中加载 ProductList。这意味着,出于性能考虑,GrandChildViewA1 应该将产品列表传递给 SelectProductViewModel,而 GrandCHildViewB2 中不会包含产品列表,因此 SelectProductViewModel 应该从数据库中获取数据。

4

2 回答 2

0

我将创建一个通用视图模型,它定义了接收数据的合同。

public abstract class PassDataViewModel<T> : ObservableObject
{
    public T Data { get; }
}

然后,我会为您的产品列表创建一个更通用的 ViewModel,如下所示:

public class SelectProductViewModel : PassDataViewModel<Product>
{
    private Product _selectedProduct;
    private ObservableCollection<Product> _products = new ObservableCollection<Product>();

    public SelectProductViewModel(IList<Product> products)
    {
        _selectedProduct = _products.First();
    }

    public IEnumerable<Product> Products
    {
        get { return _products; }
    }

    public Product SelectedProduct
    {
        get { return _selectedProduct; }
        set
        {
            _selectedProduct = value;
            OnPropertyChanged("SelectedProduct");
            OnPropertyChanged("Data");
        }
    }

    public Product Data
    {
        get { return _selectedProduct; }
    }
}

您可以通过以下方式使用它:

  1. 您的第一个 viewModel 可以创建SelectProductViewModel的实例(例如,当调用命令时)
  2. 您将产品列表传递给新的SelectProductViewModel实例。
  3. 使用 DataTemplate 更改屏幕上的视图(这篇文章将向您展示如何执行此操作)。
  4. 在父视图模型中有一个属性,该属性返回从SelectProductViewModel的数据属性返回的产品(您需要将 PropertyChanged 事件传播到父视图模型)。
于 2012-06-17T15:39:43.273 回答
0

最简单的方法是采用视图模型优先方法并使用对话服务来显示选择视图。

您的带有 ProductionList 的视图模型只需调用对话服务并将 ProductSelectionViewmodel 与 ProductionList 作为参数。因为这是视图模型,所以您必须首先创建一个数据模板,以便 WPF 知道如何呈现您的 ProductSelectionViewmodel。

是一个简单对话服务的链接。

顺便说一句:在我看来,viewmodel 第一种方法在做 mvvm 时要容易得多。

编辑:

在 SelectProductCommand 中的 ProductionListViewModel 中

 var selectProductViewModel = new SelectProductViewModel(this.ProductionList);
 var result = this.uiDialogService.ShowDialog("Select Product", selectProductViewModel );

 //if result true, simple get the selected product
 this.SelectedProduct = selectProductViewModel.MySelectedProduct;

仅此而已 - 简单易行

于 2012-06-18T06:13:25.103 回答