我遇到了绑定(bind)到 ItemsControl 的 DataTemplate 内按钮的 WPF 和命令的问题。场景非常简单。 ItemsControl 绑定(bind)到对象列表,我希望能够通过单击按钮删除列表中的每个对象。按钮执行命令,命令负责删除。 CommandParameter 绑定(bind)到我要删除的对象。这样我就知道用户点击了什么。用户应该只能删除他们“自己的”对象 - 因此我需要在命令的“CanExecute”调用中进行一些检查,以验证用户是否具有正确的权限。
问题是第一次调用时传递给 CanExecute 的参数为 NULL - 所以我无法运行逻辑来启用/禁用该命令。但是,如果我使其始终启用,然后单击按钮执行命令,则 CommandParameter 会正确传入。这意味着针对 CommandParameter 的绑定(bind)正在起作用。
ItemsControl 和 DataTemplate 的 XAML 如下所示:
<ItemsControl
x:Name="commentsList"
ItemsSource="{Binding Path=SharedDataItemPM.Comments}"
Width="Auto" Height="Auto">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button
Content="Delete"
FontSize="10"
Command="{Binding Path=DataContext.DeleteCommentCommand, ElementName=commentsList}"
CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
正如您所看到的,我有一个 Comments 对象列表。我希望将DeleteCommentCommand 的CommandParameter 绑定(bind)到Command 对象。
所以我想我的问题是:以前有人遇到过这个问题吗? CanExecute 在我的命令上被调用,但第一次参数始终为 NULL - 这是为什么?
更新:我能够稍微缩小问题范围。我添加了一个空的 Debug ValueConverter,以便在 CommandParameter 进行数据绑定(bind)时可以输出一条消息。事实证明,问题在于 CanExecute 方法是在 CommandParameter 绑定(bind)到按钮之前执行的。我尝试在命令之前设置 CommandParameter(如建议的那样) - 但它仍然不起作用。有关如何控制它的任何提示。
更新2:有什么方法可以检测绑定(bind)何时“完成”,以便我可以强制重新评估命令?另外 - 我有多个按钮(ItemsControl 中的每个项目一个)绑定(bind)到 Command 对象的同一实例,这是否是一个问题?
更新3:我已将错误的复制品上传到我的 SkyDrive:http://cid-1a08c11c407c0d8e.skydrive.live.com/self.aspx/Code%20samples/CommandParameterBinding.zip
最佳答案
我在尝试绑定(bind)到 View 模型上的命令时遇到了同样的问题。
我将其更改为使用相对源绑定(bind),而不是按名称引用元素,这就达到了目的。参数绑定(bind)没有改变。
旧代码:
Command="{Binding DataContext.MyCommand, ElementName=myWindow}"
新代码:
Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=Views:MyView}}"
更新:我刚刚在没有使用 ElementName 的情况下遇到了这个问题,我绑定(bind)到 View 模型上的命令,并且按钮的数据上下文是我的 View 模型。在这种情况下,我只需将 CommandParameter 属性移到 Button 声明中的 Command 属性之前(在 XAML 中)。
CommandParameter="{Binding Groups}"
Command="{Binding StartCommand}"
关于第一次调用 CanExecute 时 WPF CommandParameter 为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/335849/