ItemsControl中DataTemplate上的事件处理程序

Chr*_*sco 5 c# wpf mvvm

我有一个ItemsControl可以显示同一模板的多个实例。我需要能够在事件处理程序上执行代码,以便可以区分控件。

例如:我有一个杂货清单,因此我为每种食物都DataTemplate包含一个“购买” Button。我想将所述按钮绑定到代码,并告诉按下了哪个按钮。

考虑到我正在使用MVVM设计模式,我该如何做到这一点

** XAML:**

<ItemsControl ItemsSource="{Binding MyItemList}">
     <ItemsControl.ItemsTemplate>
          <DataTemplate>
              <Button Content="Buy" />
          </DataTemplate> 
     </ItemsControl.ItemsTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

所以,MyItemList是一个List<MyItem>实例。所述DataTemplate包含修改值或在执行代码中不存在控制MyItem

我已经阅读了很多关于将模板出价到命令的文章,但是找不到使用项目列表的文章。

era*_*zap 5

您需要将按钮绑定到 ItemsControl 的 DataContext 的命令。

在 WPF 中搜索命令:(常见实现):

public class RelayCommand<T> : IRelayCommand
{
    private Predicate<T> _canExecute;
    private Action<T> _execute;

    public RelayCommand(Action<T> execute, Predicate<T> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    private void Execute(T parameter)
    {
        _execute(parameter);
    }

    private bool CanExecute(T parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public bool CanExecute(object parameter)
    {
        return parameter == null ? false : CanExecute((T)parameter);
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

    public event EventHandler CanExecuteChanged;

    public void RaiseCanExecuteChanged()
    {
        var temp = Volatile.Read(ref CanExecuteChanged);

        if (temp != null)
            temp(this, new EventArgs());
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的 ViewModel 中( ItemsControl 的 DataContext ,我希望:))

   private RelayCommand<FoodItem> _addToGroceriesCommand;
   public ICommand AddToGroceriesCommand
   {
        get
        {
            if (_addToGroceriesCommand == null)
            {
                _addToGroceriesCommand = new RelayCommand<FoodItem>(OnAddToGroceries);                    
            }
            return _addToGroceriesCommand;
        }
    }

   public void OnAddToGroceries(FoodItem newItem)
   {

   }
Run Code Online (Sandbox Code Playgroud)

XAML:

   <ItemsControl ItemsSource="{Binding MyItemList}">
      <ItemsControl.ItemsTemplate>
         <DataTemplate>
             <Button Content="Buy" 
                     Command="{Binding Path=DataContext.AddToGroceriesCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
                     CommandParameter="{Binding}" />
         </DataTemplate> 
      </ItemsControl.ItemsTemplate>
   </ItemsControl> 
Run Code Online (Sandbox Code Playgroud)