2009-09-01 3 views
3

Je rencontre des problèmes lors de l'obtention d'un événement de clic sur un bouton et j'utilise Silverlight 3.0 avec Silverlight Toolkit.Silverlight: Définir le gestionnaire d'événements dans le modèle de données hiérarchique

Problème

Je possède ce TreeView:

TreeView sample http://a.imagehost.org/0939/TreeView.png.

La valeur d'un nœud donné est la somme des valeurs de ses enfants. Seules les feuilles peuvent être ajoutées (pour le moment). Ce que je veux réaliser est qu'un utilisateur peut ajouter (et finalement enlever) des entrées dans l'arbre pour finalement créer un diagramme personnalisé. À cette fin, je voudrais que le «signe plus» pour insérer une nouvelle ligne/nœud en tant qu'enfant du nœud sur lequel l'utilisateur a cliqué. (C'est à dire si je clique sur le plus à "Affichage", je reçois une ligne ci-dessous pour spécifier CRT ou TFT ou autre.)

Chose est, car tout mon cerveau vaut, je ne sais pas comment recevoir tout utile un événement. TextBlock, TextBox et Button sont définis dans un modèle hiérarchique et je ne peux pas définir de gestionnaire de clics dans ce modèle.

OTOH, je n'ai pas trouvé un moyen d'obtenir les éléments de modèle d'un certain TreeViewItem du code (C#). Très bien je suis capable de faire trv.ItemContainerGenerator.GetContainerFromItem (item), et comme Justin Angel showed je peux très bien changer la taille de la police, mais je n'ai trouvé aucun moyen d'accéder à la zone de texte ou au bouton.

Est-il possible de capturer l'événement click sur le bouton? Ou tout autre moyen d'obtenir quelque chose qui donne la fonctionnalité "ajouter ci-dessous"?

Merci d'avance.


Plus de données

Le XAML treeview est la suivante:

<controls:TreeView x:Name="SankeyDataTree" 
    ItemTemplate="{StaticResource SankeyTreeTemplate}" BorderThickness="0" 
    Background="{x:Null}" HorizontalAlignment="Left" VerticalAlignment="Top"> 
    <controls:TreeViewItem IsExpanded="True"> 
     <controls:TreeViewItem.HeaderTemplate> 
      <DataTemplate> 
       <TextBlock Text="Loading..."/> 
      </DataTemplate> 
     </controls:TreeViewItem.HeaderTemplate> 
    </controls:TreeViewItem> 
</controls:TreeView> 

J'utilise cette HierarchicalDataTemplate (et volé le appraoch de Timmy Kokke):

<Data:HierarchicalDataTemplate x:Key="SankeyTreeTemplate" ItemsSource="{Binding Children}"> 
    <Grid Height="24"> 
     <Grid.ColumnDefinitions> 
      <!-- ... --> 
     </Grid.ColumnDefinitions> 
     <TextBlock Text="{Binding Path=Value.name, Mode=TwoWay}" VerticalAlignment="Center"/> 
     <TextBox Text="{Binding Path=Value.flow, Mode=TwoWay}" Margin="4,0" VerticalAlignment="Center" d:LayoutOverrides="Width" Grid.Column="1" TextAlignment="Right" Visibility="{Binding Children, Converter={StaticResource BoxConverter}, ConverterParameter=\{box\}}"/> 
     <TextBlock Text="{Binding Path=Value.throughput, Mode=TwoWay}" Margin="4,0" VerticalAlignment="Center" d:LayoutOverrides="Width" Grid.Column="1" TextAlignment="Right" Visibility="{Binding Children, Converter={StaticResource BoxConverter}, ConverterParameter=\{block\}}"/> 
     <Button Margin="0" Grid.Column="2" Style="{StaticResource TreeViewItemButtonStyle}"> 
      <Image Source="../Assets/add.png" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
     </Button> 
    </Grid> 
</Data:HierarchicalDataTemplate> 

A cette TreeView est lié un "SimpleTree", dont les valeurs tiennent fondamentalement unle chaîne (nom) et deux doubles (flux et débit).

public String name { get; set; } 
public Double flow { get; set; } 
public Double throughput { get; set; } 

(plus le code de la INotifyPropertyChanged pour obtenir une liaison bidirectionnelle aux zones de texte.)

Répondre

3

Vous pouvez joindre un Behavior au Button dans le HierarchicalDataTemplate et laisser cette poignée Click événements de la Button.

Téléchargez et installez le Expression Blend 3 SDK. Ajouter une référence à System.Windows.Interactivity dans le projet et ajouter un Behavior attaché à un Button:

public class ButtonClickBehavior : Behavior<Button> { 

    protected override void OnAttached() { 
    base.OnAttached(); 
    AssociatedObject.Click += ButtonClick; 
    } 

    protected override void OnDetaching() { 
    base.OnDetaching(); 
    AssociatedObject.Click -= ButtonClick; 
    } 

    void ButtonClick(object sender, RoutedEventArgs e) { 
    Node node = AssociatedObject.DataContext as Node; 
    if (node != null) { 
     // Button clicked. Do something to associated node. 
    } 
    } 

} 

Fixez le Behavior au Button dans le HierarchicalDataTemplate (en supposant cette déclaration d'espace de noms: xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"):

<Button Margin="0" Grid.Column="2" Style="{StaticResource TreeViewItemButtonStyle}"> 
    <Image Source="../Assets/add.png" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
    <interactivity:Interaction.Behaviors> 
    <local:ButtonClickBehavior/> 
    </interactivity:Interaction.Behaviors> 
</Button> 

Si Vous pouvez ajouter des propriétés à ButtonClickBehavior et les définir à partir de XAML pour créer un Behavior plus réutilisable.

+0

Awesome. Merci de votre aide! Je savais que Microsoft aurait été approfondie et avait un moyen de faire ce que j'essaie de faire. ;) – Cornelius

+0

Où est la classe Node? J'ai besoin de ce comportement exact dans un UserControl WPF, mais je ne peux pas le compiler car je n'ai pas de référence à l'espace de noms pour la classe Node, et google n'a pas aidé. Merci. – Shawn

+0

La classe 'Node' est votre classe" own ". C'est la classe de l'objet que chaque noeud dans l'arborescence est lié à l'aide de la liaison de données. –

3

Vous pouvez gérer l'événement clic du bouton dans le code derrière. Pour accéder aux données, il suffit de lier l'attribut Tag.

<Button Margin="0" Grid.Column="2" 
     Click="Button_Click" Tag="{Binding}" 
     Style="{StaticResource  TreeViewItemButtonStyle}">    
    <Image Source="../Assets/add.png" Margin="0" 
     HorizontalAlignment="Center" VerticalAlignment="Center"/>   
</Button> 

Dans le code qui suit, manipulez-le et accédez à l'élément.

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    var data = ((Button)sender).Tag as SimpleTreeNode 
} 

SimpleTreeNode est le nom de votre classe d'élément d'arbre.

Vous devriez pouvoir ajouter un nouveau noeud aux données trouvées maintenant.

+0

Merci pour votre réponse :) Il a confirmé ce que je soupçonnais; Si j'ai le modèle de données hiérarchique dans ma Page.xaml, cela fonctionne. Y at-il un moyen de lier un événement au bouton si le modèle réside dans un dictionnaire de ressources (signifie, dans un fichier assez différent)? (S'il était agrégé dans App.xaml via , devrais-je placer le EventHandler dans App.xaml.cs (ou le codebehind approprié)? – Cornelius

Questions connexes