C# 您如何知道ItemsControl的哪个元素在MVVM中发送事件?

C# 您如何知道ItemsControl的哪个元素在MVVM中发送事件?,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,假设我当前有一个ItemsControl,其数据模板是一组按钮。我正在连接这些按钮的点击事件,但是我怎么知道哪个按钮被点击了呢?我不应该使用ItemsControl吗 我试图没有代码隐藏,但务实可能是必要的 <ItemsControl> <ItemsControl.ItemTemplate> <DataTemplate> <Button Margin="10"> <

假设我当前有一个ItemsControl,其数据模板是一组按钮。我正在连接这些按钮的点击事件,但是我怎么知道哪个按钮被点击了呢?我不应该使用ItemsControl吗

我试图没有代码隐藏,但务实可能是必要的

<ItemsControl>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Margin="10">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding ItemsControlButtonClicked, Mode=OneWay}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>


您可以随命令一起发送参数,根据这些参数您可以找到单击了哪个按钮

您可以随命令一起发送参数,根据这些参数您可以找到单击了哪个按钮

如果您想知道单击了什么
,然后传递
{Binding}
作为
命令参数
,它会将所选对象传递给您的命令


如果您想知道单击了什么
按钮
,我会在代码隐藏中这样做,因为ViewModels不需要了解任何有关UI的信息,而这包括按钮

另外,由于控件是按钮,因此应该使用
命令
属性,而不是单击触发器

<Button Command="{Binding ItemsControlButtonClicked}" />

如果您想知道单击了什么
,则将
{Binding}
作为
命令参数
传递,它会将所选对象传递给您的命令


如果您想知道单击了什么
按钮
,我会在代码隐藏中这样做,因为ViewModels不需要了解任何有关UI的信息,而这包括按钮

另外,由于控件是按钮,因此应该使用
命令
属性,而不是单击触发器

<Button Command="{Binding ItemsControlButtonClicked}" />

在我的项目中,我也使用MVVM指示灯。我有一个包含项目集合的下拉列表,以及一个按钮,用户按下该按钮并根据下拉列表中选定的项目执行操作 您应该创建一个带有参数的中继命令。请看我的代码中的示例

  public RelayCommand<Project> StartTimer { get; private set; }//declare command

   StartTimer = new RelayCommand<Project>(OnStartTimer);

    private void OnStartTimer(Project project)
    {

        if (project != null)
        {

            currentProject = project;

            if (!timer.IsTimerStopped)
            {
                timer.StopTimer();
            }
            else
            {
                Caption = "Stop";
                timer.StartTimer();
            }
        }
public RelayCommand StartTimer{get;private set;}//declare命令
StartTimer=新继电器命令(启动计时器);
私有void OnStartTimer(项目)
{
如果(项目!=null)
{
当前项目=项目;
如果(!timer.IsTimerStopped)
{
timer.StopTimer();
}
其他的
{
标题=“停止”;
timer.StartTimer();
}
}
在视图中,我将下拉列表与类项目集合绑定 对于按钮命令参数,我绑定所选项目表单下拉列表 看看代码

   <ComboBox Name="projectcomboBox" ItemsSource="{Binding Path=Projects}"    IsSynchronizedWithCurrentItem="True" DisplayMemberPath="FullName"
              SelectedValuePath="Name"  SelectedIndex="0"  >
    </ComboBox>
      <Button Name="timerButton" Content="{Binding Path=Caption}" Command="{Binding Path=StartTimer}" 
                CommandParameter="{Binding ElementName=projectcomboBox, Path=SelectedItem}"  ></Button>

注意命令和CommandParameter绑定


此外,您还可以使用此方法,不仅用于下拉列表,在我的项目中,我还使用MVVM指示灯。我有一个包含项目集合的下拉列表,以及一个按钮,用户按下该按钮并执行操作取决于下拉列表中的所选项目 您应该创建一个带有参数的中继命令。请看我的代码中的示例

  public RelayCommand<Project> StartTimer { get; private set; }//declare command

   StartTimer = new RelayCommand<Project>(OnStartTimer);

    private void OnStartTimer(Project project)
    {

        if (project != null)
        {

            currentProject = project;

            if (!timer.IsTimerStopped)
            {
                timer.StopTimer();
            }
            else
            {
                Caption = "Stop";
                timer.StartTimer();
            }
        }
public RelayCommand StartTimer{get;private set;}//declare命令
StartTimer=新继电器命令(启动计时器);
私有void OnStartTimer(项目)
{
如果(项目!=null)
{
当前项目=项目;
如果(!timer.IsTimerStopped)
{
timer.StopTimer();
}
其他的
{
标题=“停止”;
timer.StartTimer();
}
}
在视图中,我将下拉列表与类项目集合绑定 对于按钮命令参数,我绑定所选项目表单下拉列表 看看代码

   <ComboBox Name="projectcomboBox" ItemsSource="{Binding Path=Projects}"    IsSynchronizedWithCurrentItem="True" DisplayMemberPath="FullName"
              SelectedValuePath="Name"  SelectedIndex="0"  >
    </ComboBox>
      <Button Name="timerButton" Content="{Binding Path=Caption}" Command="{Binding Path=StartTimer}" 
                CommandParameter="{Binding ElementName=projectcomboBox, Path=SelectedItem}"  ></Button>

注意命令和CommandParameter绑定


此外,您还可以使用此方法不仅用于下拉列表,还可以使用Sender.DataContext作为实际数据。

您可以使用Sender.DataContext作为实际数据。

在视图模型类中创建命令属性(使用Josh Smith的
RelayCommand
模式是最简单的方法)并将每个按钮的
命令
绑定到相应的按钮。这不仅简单易懂且易于维护,还为您提供了在需要时实现启用/禁用行为的简便方法。

在视图模型类中创建命令属性(使用Josh Smith的
RelayCommand
模式是实现这一点的最简单方法)并将每个按钮的
命令
绑定到相应的按钮。这样做不仅简单易懂,维护也很简单,还可以在需要时轻松实现启用/禁用行为。

并且可以直接在
按钮
上设置Command\CommandParameter属性(不带
事件触发器
)为了达到同样的效果,这似乎是我一直在寻找的,但由于某些原因,没有调用该命令。该命令位于datatemplate中,这一事实是否会改变datacontext?Intellisense也无法解析该命令的符号。它试图执行的命令是
ItemsControl.Items[X].ItemsControlButtonClicked
,其类型应为
ICommand
。如果此处不存在您的命令,则需要更改绑定。我尚未使用MVVMLight的交互触发器,因此无法告诉您为什么会出现intellisense错误,但您可能需要查看其文档。另外,由于您使用按钮控件,为什么不直接使用
命令
属性而不是单击事件?请参阅对我的答案的编辑。没有原因;没有想到我想要的事件(单击)是命令的默认值。问题是我要引发的事件在UserControl的DataContext中。我试图在那里创建一个绑定来调用它,但它似乎不起作用。您呢