2009-01-18 88 views
1

我有设置ContextMenu的TabControl。从ContextMenu命令查找TabItem的正确方法

所有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模板之类的东西,就不会破坏它。

或者可能是整个方法是错误的,我不应该使用路由命令呢?我最初使用路由添加新标签命令,需要热键。

在此先感谢。

UPDATE

伊戈尔的解决方案是从建筑POV清洁剂(除了我会删除_在视图模型),但我希望有一个可重复使用的关闭命令是独立于什么TabControl的必然(因为关闭/关闭全部选项卡存在于各种应用程序中,并且没有语义链接到特定模型)。

此外,我不能使用自定义DataTemplate,因为我已经有了一个自定义模板,并且它的子类化会使解决方案有点过于复杂。

回答

1

看来我已经找到自己的答案,但它是非常unelegant:

<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

当然,还有更好的答案。您需要使用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对象和你的数据模板绑定的Data对象来找到它。

祝好来自俄罗斯!

+0

谢谢,请在原始问题结尾处查看我的回复。仍然是+1。 – 2009-02-09 10:19:54