如何将相同的命令添加到 ItemsControl 中的 WPF 按钮

How to add the same command to WPF buttons in ItemsControl

如何将命令添加到作为 ItemsControl 的一部分并且正在修改 ItemsSource 本身的 wpf 按钮?

这是我的 XAML:

<ItemsControl ItemsSource="{Binding PluginVMs}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Button x:Name="btnStampDuplicate" 
                        Content="Duplicate this control"
                        Command="{Binding ?????????}"/>
                <!-- other stuff -->
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

这是我的视图模型:

public ObservableCollection<PluginViewModel> PluginVMs
{
    get { return _pluginVMs; }
    set
    {
        if (_pluginVMs != value)
        {
            _pluginVMs = value;
            NotifyPropertyChanged("PluginVMs");
        }
    }
}

如您所见,PluginVMsPluginViewModel 的集合。所以我知道 btnStampDuplicate 中可用的命令应该在 PluginViewModel 中实现。

但是,正如名称 duplicate 所暗示的,我想在 PluginVMs 中复制当前生成的 PluginViewModel。为 btnStampDuplicate 提供这种功能的最佳方法是什么?

没有必要在每个项目中都有一个命令。您可以使用 CommandParameter 传递一个欺骗源的项目

在 DataTemplate 绑定命令中使用 ElementName 访问更高级别的 DataContext

查看

<ItemsControl Name="ListPlugins" ItemsSource="{Binding PluginVMs}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Button x:Name="btnStampDuplicate" 
                        Content="duplicate"
                        CommandParameter={Binding Path=.}
                        Command="{Binding Path=DataContext.DupeCmd, ElementName=ListPlugins}"
                />
                <!-- other stuff -->
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

视图模型

public class Vm
{
    public ObservableCollection<PluginViewModel> PluginVMs
    {
        get { return _pluginVMs; }
        set
        {
            if (_pluginVMs != value)
            {
                _pluginVMs = value;
                NotifyPropertyChanged("PluginVMs");
            }
        }
    }

    public ICommand DupeCmd { get; private set; }
}