2013-12-19 198 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,直接等)。