我有TabControl,我正在设置ContextMenu。
所有ContextMenu元素都设置了命令。
<ContextMenu x:Key="tabMenu">
<MenuItem Command="{x:Static tabs:TabCommands.Close}" />
<MenuItem Command="{x:Static tabs:TabCommands.CloseAllButThis}" />
<MenuItem Command="{x:Static tabs:TabCommands.CloseAll}" />
</ContextMenu>
所有命令都被路由,并且CommandBindings被定义在TabControl之上的几个级别。
所以问题是:在CommandBinding CanExecute / Execute事件处理程序中,找出调用菜单的TabItem的正确方法是什么?正确的意思是指如果我改变像TabItem模板那样不会破坏的那个。
或者整个方法可能是错误的,我不应该使用路由命令?我最初使用路由添加新标签命令,这需要热键。
提前致谢。
更新:
Igor的解决方案来自架构POV更清晰(除了我会在ViewModel中删除_),但我希望有一个可重用的Close命令,它独立于TabControl的绑定(因为所有选项卡都有关闭/关闭所有)各种应用程序,并且没有语义链接到特定模型。)
另外,我不能使用自定义DataTemplate,因为我已经有了一个自定义模板,并且对它进行子类化会使解决方案过于复杂。
答案 0 :(得分:1)
似乎我自己找到了答案,但它非常不优雅:
<Style TargetType="MenuItem">
<Setter Property="CommandTarget">
<Setter.Value>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}"
Path="(ContextMenu.PlacementTarget)" />
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TabItem">
<Setter Property="ContextMenu" Value="{StaticResource tabMenu}" />
</Style>
所以我将ContextMenu添加到TabItem而不是TabControl,并将CommandTarget绑定到TabItem。
是否有更好的答案很有意思。
答案 1 :(得分:1)
当然,有一个更好的答案。您需要使用Model / ViewModel,而不是查看。这是我的代码中简化的例子:
<TabControl Margin="3" Grid.Column="1" Name="tbPages"
ItemsSource="{Binding DsmProject.Pages}"
ItemTemplate="{DynamicResource TabItemTemplate}"
IsSynchronizedWithCurrentItem="True">
</TabControl>
<DataTemplate x:Key="TabItemTemplate">
<StackPanel Orientation="Horizontal" ContextMenu="{DynamicResource cmPages}">
<ContentPresenter Content="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
<ContextMenu x:Key="cmPages">
<MenuItem Header="Close" Command="cmd:DSM2100Commands.ClosePage" CommandParameter="{Binding}" />
</ContextMenu>
以下是处理此命令的代码。
Private Sub ClosePageCmd(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
ViewModel_.History.TakeCommmand(New cmdRemovePage(ViewModel_, e.Parameter))
End Sub
Private Sub CanClosePageCmd(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
e.CanExecute = ViewModel_.DsmProject IsNot Nothing AndAlso ViewModel_.DsmProject.Pages.Count > 1
End Sub
如您所见,我的代码不需要知道单击了哪个TabItem,只需要知道哪个数据对象绑定到此TabItem。无论如何,如果你需要知道TabItem,它被点击了你可以通过使用ContainerGenerator对象和你的datatemplate绑定到它的Data对象找到它。
带着俄罗斯的祝福!