2009-07-23 6 views
1

J'insère TreeViewItems dans un contrôle TreeView et définissant le style pour chacun au moment de l'insertion. J'attribue différents styles (prédéfinis en XAML), en fonction du type de noeud (TreeViewItem) que je veux insérer. Certains styles incluent un ContextMenu.Comment faire pour obtenir des événements MenuItem cliqués à partir de TreeView ContextMenu

Mon problème est que je suis incapable d'utiliser Click = "MyHandler" sur le MenuItems; Je reçois une erreur "élément racine nécessite un attribut x: Class pour prendre en charge les gestionnaires d'événements dans le fichier XAML." et apparemment, aucun des éléments du bloc Style n'est un élément racine.

Toutes les suggestions très appréciées.

XAML:

<Style x:Key="Terrain" TargetType="{x:Type TreeViewItem}"> 
    <Setter Property="HeaderTemplate"> 
     <Setter.Value> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <Canvas Background="{DynamicResource Terrain_icon}" /> 
       <TextBlock Text="{Binding}" /> 
       <StackPanel.ContextMenu> 
        <ContextMenu> 
         <MenuItem Header="Edit..." Click="MyHandler"/> <!-- Error --> 
         <MenuItem Header="Add..."/> 
         <MenuItem Header="Delete"/> 
        </ContextMenu> 
       </StackPanel.ContextMenu> 
      </StackPanel> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

C#:

private void InsertTerrainNode(object sender, System.Windows.RoutedEventArgs e) 
{ 
    // Add the new item under the first-level TreeViewItem 
    TreeViewItem tvi = myTree.ItemContainerGenerator.ContainerFromItem(myTree.Items[0]) as TreeViewItem; 
    TreeViewItem newTerrainNode = new TreeViewItem(); 
    newTerrainNode.Header = "Terrain"; 
    newTerrainNode.Style = (Style)this.FindResource("Terrain"); 
    tvi.Items.Insert(0,newTerrainNode); 
} 

Répondre

1

Utilisez les commandes, créer une classe dérivée de ICommand, déclarer dans la classe qui ont accès aux controles utilisateur et est accessible dans votre XAML et se lient bouton avec cette commande. voir here pour les détails

0

Une autre option consiste à ajouter un gestionnaire d'événements pour l'événement MenuItem.Click au TreeViewItem lors de sa création.

private void InsertTerrainNode(object sender, System.Windows.RoutedEventArgs e) 
{ 
    // Add the new item under the first-level TreeViewItem 
    TreeViewItem tvi = myTree.ItemContainerGenerator.ContainerFromItem(myTree.Items[0]) as TreeViewItem; 
    TreeViewItem newTerrainNode = new TreeViewItem(); 
    newTerrainNode.Header = "Terrain"; 
    newTerrainNode.Style = (Style)this.FindResource("Terrain"); 
    newTerrainNode.AddHandler(MenuItem.Click, OnTreeItemContextMenuClicked); 
    tvi.Items.Insert(0,newTerrainNode); 
} 

private void OnTreeItemContextMenuClicked(object sender, RoutedEventArgs e) 
{ 
    // Handle the ContextMenu item click here 
    // e.OriginalSource can be used to get the ContextMenu item clicked if needed. 
} 
+0

Merci Andy, cela m'a fait sur la bonne voie je pense. J'ai maintenant C#: newTerrainNode.ContextMenu.AddHandler (MenuItem.ClickEvent, nouveau RoutedEventHandler (OnTreeItemContextMenuClicked)); Cependant, j'obtiens une erreur d'exécution: Exception non gérée: System.NullReferenceException: Référence d'objet non définie sur une instance d'un objet. à TreeTest2.MainWindow.InsertTerrainNode (Expéditeur d'objet, RoutedEventArgs e) Des idées? –

+0

Quelle ligne de votre gestionnaire d'événement lance l'exception? – Andy

+0

Lorsque le gestionnaire d'événement est ajouté - newTerrainNode.AddHandler (MenuItem.Click, OnTreeItemContextMenuClicked); Je pensais que c'était peut-être parce que le TreeViewItem n'avait pas été inséré dans l'arbre à ce moment, mais j'ai la même erreur (pour la même ligne de code) si j'ajoute le gestionnaire après tvi.Items.Insert (0, newTerrainMode); –

Questions connexes