2012-11-16 7 views
8

So zeigen Sie das Kontextmenü für den Strukturansichtselement in wpf mit der hierarchischen Datenvorlage an? Wie Kontextmenü angezeigt werden nur für CountryTemplate:So zeigen Sie das Kontextmenü für den TreeView-Eintrag in einer hierarchischen Datenvorlage in wpf an

<HierarchicalDataTemplate x:Key="DispTemplate"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" Tag="{Binding Path=Tag}"> 
      </TextBlock> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
    <HierarchicalDataTemplate x:Key="BuildingTemplate" ItemsSource="{Binding Path=Building}" ItemTemplate="{StaticResource BuildingTemplate}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
    <HierarchicalDataTemplate x:Key="CityTemplate" ItemsSource="{Binding Path=City}" ItemTemplate="{StaticResource CityTemplate}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
    <HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemTemplate="{StaticResource CountryTemplate}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/> 
     </StackPanel> 
    </HierarchicalDataTemplate> 

Antwort

11

Sie können auch die ContextMenu ein visuelles Kind hinzufügen hinzufügen können in die Datenvorlage, zum Beispiel:

<HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemTemplate="{StaticResource CountryTemplate}"> 
    <StackPanel Orientation="Horizontal"> 
     <StackPanel.ContextMenu> 
      <ContextMenu> 
       <MenuItem Header="Header" Command="{Binding Command}"/> <!--This command should be in the data context (each country item)--> 
      </ContextMenu> 
     </StackPanel.ContextMenu> 
     <TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/> 
    </StackPanel> 
</HierarchicalDataTemplate> 
+0

Wie binde ich an den Befehl, der im Stammverzeichnis des Viewmodels definiert ist. Bisher funktioniert die FindAncestor-Methode nicht. Kannst du mir bitte ein Beispiel dafür zeigen? – TrustyCoder

+0

In den Fällen, in denen ich nicht einfach auf das View-Modell zugreifen kann, um die Bindung zu erstellen, versuche ich mit dieser FindAncestor-Bindung: Command = "{Binding DataContext.Command, RelativeSource = {RelativeSource FindAncestor, AncestorType = {x: Type MainWindow}}} "Im Allgemeinen hat der Datenkontext des Hauptfensters das Root-View-Modell und es gibt den gewünschten Befehl. –

+0

Das funktioniert aus irgendeinem Grund nicht mit dem Kontextmenü, da es nicht Teil der visuellen Struktur ist. – TrustyCoder

3
<HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemContainerStyle="{StaticResource CountryTemplateItemContainerStyle}" ItemTemplate="{StaticResource CountryTemplate}"> 
         <StackPanel Orientation="Horizontal"> 
          <TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" /> 
         </StackPanel> 
</HierarchicalDataTemplate> 


<Style x:Key="CountryTemplateItemContainerStyle" TargetType="{x:Type TreeViewItem}"> 
<Setter Property="ContextMenu" Value="{DynamicResource TreeViewContextMenu}"/> 
</Style> 
<ContextMenu x:Key="TreeViewContextMenu"> 
     <MenuItem .../> 
</ContextMenu> 

Wie Sie sehen können, können Sie Ihre contextmenu im ItemContainerStyle der HierarchicalDataTemplate

+0

Das hat bei mir nicht funktioniert. – TrustyCoder

+0

Dies funktionierte gut für mich, und ich mag, wie das ContextMenu in der Nähe des Elements definiert ist. –

+0

Das hat für mich funktioniert. Um einen Kompilierfehler zu vermeiden, musste ich die Blöcke tauschen (stelle sicher, dass die XAML-Tags 'HierarchicalDataTemplate' hinter den Tags' Style' und 'ContextMenu' stehen). Der Grund dafür ist, dass das Verschieben des ContextMenu in einen Stil alles in einen engeren visuellen Baum verschiebt, was bedeutet, dass der DataContext ohne Probleme gefunden werden kann. – Contango

3

Im Grunde kam ich mit diesen

bis
<HierarchicalDataTemplate x:Key="ChildTemplate"> 
      <StackPanel Orientation="Horizontal"> 
       <StackPanel.ContextMenu> 
        <ContextMenu> 
         <MenuItem Header="Copy" CommandParameter="{Binding CopyTag}"> 
         </MenuItem> 
         <MenuItem Header="Paste" CommandParameter="{Binding PasteTag}"> 
         </MenuItem> 
         <ContextMenu.ItemContainerStyle> 
          <Style TargetType="MenuItem"> 
           <Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CopyPaste}"/> 
          </Style> 
         </ContextMenu.ItemContainerStyle> 
        </ContextMenu> 
       </StackPanel.ContextMenu> 
       <Image Source="/Images/Child.png" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" Style="{StaticResource TreeIconStyle}"/> 
       <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" Tag="{Binding Path=Tag}"> 
       </TextBlock> 
      </StackPanel> 
     </HierarchicalDataTemplate> 

Und haben separate Parameter zum Kopieren und Einfügen, um Kopieren und Einfügen in einem einzigen Befehl zu unterscheiden.

2

Einer der Gründe, warum Kontextmenüs nicht so sauber arbeiten, wie sie könnten, ist, weil sie sich standardmäßig in einem anderen visuellen Baum befinden als alles andere, so dass DataContext nicht gefunden werden kann.

Der Schlüssel ist es, einen Einblick <Style> zu schaffen, die ein Kontextmenü definiert, dann diesen Stil zu einem Zielelement befestigen, die den Kontext Menü Haken auf. Dies verschiebt das Kontextmenü in eine visuelle Struktur, die mit dem Standard DataContext ausgerichtet ist, den Sie möchten.

Erstellen Sie zunächst den Stil:

<UserControl.Resources>                               
    <ResourceDictionary> 

     <!-- For the context menu to work, we must shift it into a style, which means that the context menu is now in a 
     visual tree that is more closely related to the current data context. All we have to do then is set the style, 
     which hooks up the context menu. --> 
     <Style x:Key="ContextMenuStyle" TargetType="{x:Type StackPanel}"> 
      <Setter Property="ContextMenu" Value="{DynamicResource TreeViewContextMenu}"/> 
     </Style> 
     <ContextMenu x:Key="TreeViewContextMenu"> 
      <MenuItem Header="Test" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CmdDisplayDetailsGraph}"/> 
     </ContextMenu> 

Dann das Kontextmenü anschließen wo immer Sie wollen, ohne durch verschiedene visuelle Bäume verursacht in Probleme zu laufen.

Beispiel 1:

<HierarchicalDataTemplate DataType="{x:Type snapshot:Details}" ItemsSource="{Binding DetailsList}"> 
    <StackPanel Orientation="Vertical" Style="{StaticResource ContextMenuStyle}"> 
     <ContentPresenter Content="{Binding}" ContentTemplate="{Binding View.DefaultDataRowTemplate}" /> 
</StackPanel> 

Beispiel 2:

<DataTemplate DataType="{x:Type snapshot:InstrumentDetails}"> 
    <StackPanel Orientation="Vertical" Style="{StaticResource ContextMenuStyle}">     
     <Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">