使用命令绑定将数据从视图发送到viewmodel

时间:2009-11-03 19:24:15

标签: wpf mvvm commandbinding

问题: 使用命令绑定时如何将数据发送到视图模型?因此,例如,当我单击一个按钮时,它会发送列表的“当前选定索引”,以便它可以对列表中的该项执行操作


更多信息: 我正在制定一个程序,我有一个货物清单,每个货物都有一个托盘清单。我想制作一个按钮,允许我在当前选择的货件中添加新托盘。 >编辑>通过另一个扳手进入工程,每个托盘都有一个产品清单。因此,我不仅需要知道我的货物是什么,而且我还需要知道我所装货物的托盘。

当我执行命令绑定时,我不知道如何将数据发送到ViewModel。我想保留这个纯MVVM,所以我不想让ViewModel检查视图中的任何内容。

〜n的


编辑: 11/04/09 - 我删除了有关ViewModel实例化的问题部分。我会再问一个不同的问题,因为这个问题正在顺利解决另一个问题。我对这个问题做了一些其他修改,以便按照我想要的方向进行澄清。并且改变了一些语法位,这样当只有一个时,它就不是在讨论两个问题。

2 个答案:

答案 0 :(得分:2)

我通常从视图模型中公开CollectionView,并在ItemsControl上设置显示视图中列表的IsSynchronizedWithCurrentItem属性。然后当执行命令时,我可以检查CollectionView.CurrrentItem propety以查看当前选择的内容。

编辑:这个答案解决了你的问题中的第一个问题。 ViewModel不会您的视图将当前所选项目发送到ViewModel,而是跟踪当前所选项目。因此,使用此技术,您无需了解如何发送该信息。

在您的视图模型中有类似的内容:

class ApplicationViewModel
{
    // Exposes a list of ShipmentViewModels.
    public CollectionView Shipments { get; private set; }

    // A DelegateCommand or similar, that when executed calls AddPallet().
    public ICommand AddPalletCommand { get; private set; }

    void AddPallet()
    {
        ShipmentViewModel shipment = (ShipmentViewModel)Shipments.CurrentItem;
        shipment.Pallets.Add(new PalletViewModel(...));
    }
}

然后在你的xaml中:

<ListBox ItemsSource="{Binding Shipments}" IsSynchronizedWithCurrentItem="True"/>
<Button Command="{Binding AddPalletCommand}>Add Pallet</Button>

通过这种方式,您还可以从ViewModel跟踪Shipments集合的选择,并更新命令的CanExecute状态。

这对你有帮助吗?

答案 1 :(得分:0)

为了跟踪当前选择的项目,我执行与 Groky 类似的操作,也许这个示例更有意义。

在包含列表绑定的集合的ViewModel中(我在此示例中使用了ListBox)公开了与所选项目相关的属性。

// Assuming your using the MVVM template from Microsoft
public class PalletListViewModel : ViewModelBase
{
   // The collection our list is bound to
   private ObservableCollection<Pallet> _palletList;
   // The current selected item
   private Pallet _selectedPallet;
   // Our command bound to the button
   private DelegateCommand _processCommand;

   public ObservableCollection<Pallet> PalletList
   {
      get { return _palletList; }
   }

   public Pallet SelectedPallet
   {
      get { return _selectedPallet; }
      set
      {
         if(value == _selectedPallet)
            return;

         _selectedPallet = value;

         // INotifyPropertyChanged Method for updating the binding
         OnPropertyChanged("SelectedPallet");
      }
   }

   public ICommand ProcessCommand
   {
      get
      {
         if(_processCommand == null)
            _processCommand = new DelegateCommand(Process);
         return _processCommand;
      }
   }

   private void Process()
   {
      // Process the SelectedPallet
   }
}

<Window ...>
   <Grid x:Name="LayoutRoot">
      <Button Content="Process Pallet" Command="{Binding ProcessCommand}" />
      <ListBox ItemsSource="{Binding PalletList}" SelectedItem="{Binding SelectedPallet}">
         ...
      </ListBox>
   </Grid>
</Window>

希望这就是你要找的东西。