将集合传递给viewmodel并返回所选项

时间:2012-06-17 15:18:26

标签: wpf mvvm

我有一个View / ViewModel,其中加载了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应该从数据库中获取数据。

2 个答案:

答案 0 :(得分:0)

我会创建一个通用的viewModel,它定义了一个接收数据的合约。

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更改屏幕上的视图(this帖子将向您显示如何执行此操作。)
  4. 在父viewModel中有一个属性,该属性返回从 SelectProductViewModel 的data属性返回的产品(您需要将PropertyChanged事件传播到父viewModel)。

答案 1 :(得分:0)

最简单的方法是使用viewmodel第一种方法并使用对话服务来显示选择视图。

带有ProductionList的viewmodel只需调用dialogservice并将带有ProductionList的ProductSelectionViewmodel作为参数。因为这是viewmodel首先你必须创建一个datatemplate,所以WPF知道如何渲染你的ProductSelectionViewmodel。

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

btw:在我看来,在使用mvvm时,viewmodel第一种方法要容易得多。

编辑:

在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;

全部 - 简单易行