在 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 代码隐藏中添加了绑定代码。我不知道这是相关信息,否则我会在开始时添加它..(:
这是行不通的,因为你已经尝试Bind了Command到ItemsControl,而不是Button控制。你试过这个吗?:
<DataTemplate>
<Button Content="{Binding}" Command="{Binding DataContext.ZoomToAddressCommand,
RelativeSource={RelativeSource AncestorType={x:Type
YourViewNamespace:YourViewName}}}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
我们在这里尝试做的是Bind从DataTemplate我假设设置为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被设置为在对象(您的视图模型)财产DataContext的TabItem......还有我们。