2012-11-16 15 views
8

Come visualizzare il menu di scelta rapida per la visualizzazione ad albero in wpf utilizzando il modello di dati gerarchici? Come visualizzare il menu contestuale solo per CountryTemplate:Come visualizzare il menu di scelta rapida per la voce treeview in un modello di dati gerarchici nel wpf

<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> 

risposta

11

È inoltre possibile aggiungere il ContextMenu ad ogni minore visivo in il modello di dati, per esempio:

<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

Come eseguire il binding al comando definito nella radice del modello di visualizzazione. Finora il metodo FindAncestor non funziona. Puoi per favore mostrarmi un esempio di questo? – TrustyCoder

+0

In quei casi in cui non riesco ad accedere facilmente al modello di vista per creare l'associazione, provo con questo legame FindAncestor: Command = "{Binding DataContext.Command, RelativeSource = {RelativeSource FindAncestor, AncestorType = {x: Tipo MainWindow}}} ", in generale il datacontext della finestra principale ha il modello di visualizzazione di root, e c'è il comando che vuoi. –

+0

Questo non funziona con il menu di scelta rapida per qualche motivo perché non fa parte dell'albero visivo. – 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> 

Come si può vedere, è possibile aggiungere il vostro menu contestuale nel ItemContainerStyle del HierarchicalDataTemplate

+0

questo non ha funzionato per me. – TrustyCoder

+0

Questo ha funzionato perfettamente per me e, mi piace come il ContextMenu sia definito vicino all'elemento. –

+0

Questo ha funzionato per me. Per evitare un errore di compilazione, ho dovuto sostituire i blocchi (assicurati che i tag XAML 'HierarchicalDataTemplate' vengano dopo i tag' Style' e 'ContextMenu'). Il motivo per cui funziona è che lo spostamento di ContextMenu in uno stile sposta tutto in un albero visivo più strettamente correlato, il che significa che DataContext può essere trovato senza problemi. – Contango

3

Fondamentalmente mi si avvicinò con questo

<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> 

E avere parametri separati per copia e incolla per differenziare copia e incolla in un unico comando.

2

Uno dei motivi per cui i menu di scelta rapida non funzionano nel modo più pulito possibile è perché, in base all'impostazione predefinita, si trovano in un albero visivo diverso rispetto a tutto il resto, quindi non è possibile trovare DataContext.

L'intuizione fondamentale è quello di creare un <Style> che definisce un menu di contesto, quindi allegare che lo stile di un elemento di destinazione, che aggancia il menu contestuale. Questo sposta il menu di scelta rapida in un albero visivo allineato con lo DataContext predefinito desiderato.

In primo luogo, creare lo stile:

<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> 

Quindi, agganciare il menu contestuale da nessuna parte che si desidera, senza incorrere in problemi causati da diversi alberi visive.

Esempio 1:

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

Esempio 2:

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