2011-09-28 5 views
13

Sono nuovo in WPF, anche se ho qualche esperienza con WinForms. Voglio solo aggiungere ContextMenu per diversi oggetti che creo dinamicamente, ma non ho trovato nessun componente ContextMenu in VS toolbox. L'unico modo che ho trovato è quello di creare ContextMenu in fase di esecuzione in questo modo:ContextMenu in WPF

ContextMenu pMenu = new ContextMenu(); 
MenuItem item1 = new MenuItem(); 
MenuItem item2 = new MenuItem(); 

//I have about 10 items 
//... 
item1.Header = "item1"; 
item1.Click += new RoutedEventHandler(item1_Click); 
pMenu.Items.Add(item1); 

item2.Header = "item2"; 
item2.Click += new RoutedEventHandler(item2_Click); 
pMenu.Items.Add(item2); 

//and so on 

Funziona, però, in WinForms sono stato in grado di abbandonare componente ContextMenuStrip alla mia forma e definire gli elementi e gli eventi molto rapidamente w/o scrittura di qualsiasi codice. È possibile in WPF?

risposta

29

È possibile definire il proprio ContextMenu in risorse e collegarlo a qualsiasi controllo necessario. Check this out:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Window.Resources> 
     <ContextMenu x:Key="MyContextMenu"> 
      <MenuItem Header="Send" /> 
     </ContextMenu> 
    </Window.Resources> 
    <Grid> 
     <Button Name="a_button" 
      ContextMenu="{StaticResource MyContextMenu}" > 
     </Button> 
    </Grid> 
</Window> 
+1

Ok, ma creo gli oggetti dinamicamente, quindi come associarli in runtime? – Mike

+0

@ Michael: dovresti essere in grado di ottenere il ContextMenu in runtime tramite 'var pMenu = (ContextMenu) this.Resources [" MyContextMenu "];' Quindi puoi assegnare questa variabile al tuo controllo creato dinamicamente. – Heinzi

+0

Grazie, funziona. L'unica cosa che non riesco a capire è perché in WPF devo fare tutta questa magia e non ci sono componenti e GUI appropriati in IDE per rendere le cose molto più semplici come devono essere. – Mike

11

Additionaly si può mettere comandi del menuItem ...

Ti piace questa:

<MenuItem Header="MyContextMenuItem 
        Command="{Binding Path=MyCommand}" 
        CommandTarget="{Binding 
           RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type DataGrid}}}"> 

CommandTarget può essere molto importante, se si utilizza il contextMenu su diversi controlli . Io uso spesso FindAncestor qui, per identificare il chiamante.

+1

Io uso PlacementTarget per ottenere il chiamante – Mike

1

Il seguente codice funziona per me, InsertQuery/DeleteQuery sono due metodi ICommand definiti in ViewModel.

<DataGrid.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Insert" 
         Command="{Binding DataContext.InsertQuery, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/> 
      <MenuItem Header="Delete" 
         Command="{Binding DataContext.DeleteQuery, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/> 
     </ContextMenu> 
    </DataGrid.ContextMenu>