2009-01-18 153 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