将按钮绑定到 ItemsControl 容器内的 RelayCommand

Rob*_*Rob 1 c# wpf mvvm

在 WPF 应用程序中,我有一个 ViewModel,它公开了一组字符串,我使用 WrapPanel 通过 ItemsControl 容器将这些字符串显示为按钮。但是,我无法将 ViewModel 中的 RelayCommand 绑定到按钮。

视图模型(事件地址视图模型):

public IEnumerable<string> Addresses { get; set; }

public RelayCommand<string> ZoomToAddressCommand { get {
  if (this.zoomToAddressCommand == null) this.zoomToAddressComamnd = new RelayCommand<string>(this.ZoomToAddress);
  return this.zoomToAddressCommand;
}}

private void ZoomToAddress(string address) { MessageBox.Show (address); }
Run Code Online (Sandbox Code Playgroud)

XAML:

<TabItem x:Name="IncidentAddressesTab">
  <ItemsControl ItemsSource="{Binding Addresses}">
    <i:Interaction.Triggers>
      <i:EventTrigger EventName="Command">
        <cmd:EventToCommand 
          Command="{Binding ZoomToAddressCommand}"
          CommandParameter="{Binding Text}"
         PassEventArgsToCommand="True" 
        />
      </i:EventTrigger>
    </i:Interaction.Triggers>

    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <WrapPanel Orientation="Vertical"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Button Content="{Binding}" />
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</TabItem>
Run Code Online (Sandbox Code Playgroud)

连接 DataContext 的 Xaml 代码隐藏

IncidentAddressesTab.DataContext = new IncidentAddressesViewModel();
Run Code Online (Sandbox Code Playgroud)

按钮与地址一起显示。当我在 ZoomToAddressCommand 上设置断点时,它确实被击中了一次,但是当我单击按钮时,ZoomToAddress 方法永远不会被调用。

更新以包含绑定详细信息:我实际上绑定到 TabItem。我已更新 XAML 以包含附加标记,并在 XAML 代码隐藏中添加了绑定代码。我不知道这是相关信息,否则我会在开始时添加它..(:

She*_*dan 5

这是行不通的,因为你已经尝试BindCommandItemsControl,而不是Button控制。你试过这个吗?:

<DataTemplate>
    <Button Content="{Binding}" Command="{Binding DataContext.ZoomToAddressCommand, 
        RelativeSource={RelativeSource AncestorType={x:Type 
        YourViewNamespace:YourViewName}}}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

我们在这里尝试做的是BindDataTemplate我假设设置为DataContext当前视图的视图模型。请将“ YourViewNamespace:YourViewName”替换为您的 XML 命名空间和视图的实际名称。

更新 >>>

好的,再次查看您的代码后,我可以看到您只需使用属性名称Binding即可访问Addresses集合。你说 是在DataContext上设置的ItemsControl,所以我假设你的意思是你的视图模型是在ItemsControl.DataContext属性上设置的。如果是这样,那么我们需要将我们Binding的更改为Command这样:

<DataTemplate>
    <Button Content="{Binding}" Command="{Binding DataContext.ZoomToAddressCommand, 
        RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

如果您的视图模型没有在ItemsControl.DataContext属性上设置,那么这将不起作用,您需要清楚地告诉我您是如何将视图模型连接到视图的。在我假设您的视图模型是绑定到DataContext包含视图的数据之前,或者Window按照通常的做法……也许下次,您可以在您的问题中提供此信息,以便人们更轻松地回答它?

更新 2 >>>

好的,你已经用基本DataContext信息更新了问题......完美。现在,我无需猜测就可以正确回答您的问题……如果您首先在那里添加它,您是否看到这会容易得多?没关系……我们现在就在这里。试试这个最后的例子:

<DataTemplate>
    <Button Content="{Binding}" Command="{Binding DataContext.ZoomToAddressCommand, 
        RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

重申...这RelativeSource Binding将查找可视化树,直到找到一个TabItem控件。然后,它将查看DataContext该控件的属性。最后,它会寻找一个ZoomToAddressCommand被设置为在对象(您的视图模型)财产DataContextTabItem......还有我们。