2013-12-19 61 views
1

我正在处理一个WPF项目,并试图遵循MVVM模式。在过去,我只使用DataTemplates来显示信息,但现在我想在我的模板上放一个按钮,执行与包含点击按钮的项目相关的操作。我试图找出将代码绑定到我的按钮的最佳方式,以便代码知道哪个按钮被点击。WPF命令绑定到MVVM的DataItemTemplate

我的WindowViewModel包含通过命令属性公开的继电器命令,以及'Items'的ObservableCollection

public class WindowViewModel 
{ 
    public ICommand ChangeItemCommand { get; private set; } 

    public ObservableCollection<Item> Items {get;private set;} 

    public WindowViewModel() 
    { 
     ChangeItemCommand = new RelayCommand(new Action<object>(this.ChangeItem)); 
     Items = new ObservableCollection<Item>(); 
    } 

    public void ChangeItem(object o) 
    { 
     string key = (string)o; 
     //do something to the item with provided key 
    } 
} 

ItemViewModel包含ItemKey属性标识项目。

public class ItemViewModel 
{ 
    public string ItemName { get; private set; } 
    public string ItemKey { get; private set; } 
} 

我的列表框DataTemplate看起来像这样。

<DataTemplate DataType="local:ItemViewModel"> 
    <StackPanel Orientation="Horizontal"> 
     <Label Content="{Binding ItemName}"/> 
      <Button Command="???" CommandParameter="{Binding ItemKey}"/> 
     </StackPanel> 
</DataTemplate> 

所以我想弄清楚的按钮命令绑定到WindowViewModelWindowViewModel.ChangeItemCommand的最佳途径。我在考虑

一种办法是将命令添加属性时被WindowViewModel

public class ItemViewModel 
{ 
    public string ItemName { get; private set; } 
    public string ItemKey { get; private set; } 
    public ICommand ChangeItemCommand{ get; private set; } 
} 

<Button Command="{Binding ChangeItemCommand}" CommandParameter="{Binding ItemKey}"/> 

创建的实例或者我可以通过使用RelativeSource直接绑定到WindowViewModel.ChangeItemCommand属性被设置了ItemViewModel

<Button 
    Command="{Binding Path=ChangeItemCommand, 
        RelativeSource={RelativeSource AncestorType={x:Type MyAppAWindow}}}" 
    CommandParameter="{Binding ItemKey}"/> 

注:我不能完全肯定我这样做,这将被推荐,或者是有其他更好的办法正确

所以呢?

回答

0

后者是首选的。

有几种方法,它归结为偏好。有很多MVVM Frameworks,比如MVVM-LightCaliburn Micro,与纯WPF CommandBindings相比,它使得绑定命令的方式更简单。

2

这两个选项都很好,但真正做出的决定是谁应该是此操作的所有者,在MVVM中,视图模型应该先设计好,然后视图才能正确使用它们。

例如,

  • 如果这个动作是说的removeItem话,我会说这属于WindowViewModel(因为这是要改变其WindowViewModel公开集合)。

  • 但表示这一行动是RefreshItemDataChangeItemDetails(如ItemNameItemStatus),那么它属于ItemViewModel(因为这ItemViewModel可以在其它窗口中使用支持该操作)

所以,我会建议您首先要设计考虑功能性,可重用性等的ViewModel。然后使用合适的绑定特征(即,RelativeSource,ElementName,直接等)。