2009-02-23 8 views
0

J'ai un canevas WPF avec des objets Ellipse (affichés sous forme de cercles). Chaque cercle provient d'une instance de classe de collection qui est en fait une classe de modèle de trou personnalisé. Chaque motif a un certain nombre de cercles, et chaque cercle est ensuite ajouté à la toile en utilisant une itération sur la collection en utilisant le code ci-dessous. Par conséquent, le canevas est rempli d'un groupe de cercles et chaque cercle appartient à une instance de motif donnée. Vous pouvez voir une capture d'écran ici: http://twitpic.com/1f2ci/fullSélection d'un objet sur un canevas WPF?

Maintenant, je veux ajouter la possibilité de cliquer sur un cercle sur la toile, et être en mesure de déterminer la collection à laquelle elle appartient, de sorte que je puisse alors faire un peu plus de travail sur le motif sélectionné auquel appartient ce cercle.

public void DrawHoles() 
{ 
    // Iterate over each HolePattern in the HolePatterns collection... 
    foreach (HolePattern HolePattern in HolePatterns) 
    { 
     // Now iterate over each Hole in the HoleList of the current HolePattern... 
     // This code adds the HoleEntity, HoleDecorator, and HoleLabel to the canvas 
     foreach (Hole Hole in HolePattern.HoleList) 
     { 

      Hole.CanvasX = SketchX0 + (Hole.AbsX * _ZoomScale); 
      Hole.CanvasY = SketchY0 - (Hole.AbsY * _ZoomScale); 
      canvas1.Children.Add(Hole.HoleEntity); 
     } 
    } 
} 

Répondre

2

Tous FrameworkElements ont une propriété Tag qui est l'objet de type qui peut être utilisé pour contenir des informations arbitraires. Vous pouvez affecter le HolePattern à la propriété Tag et l'utiliser facilement pour récupérer la collection associée.

i.e. .:

... 
Hole.HoleEntity.Tag = HolePattern as object; 
canvas1.Children.Add(Hole.HoleEntity); 

plus tard en cas de clic:

event(object sender,....) 
{ 
    Ellipse e = sender as Ellipse; 
    HolePattern hp = e.Tag as HolePattern; 
    ... 
} 
+0

Aide génial ... vous m'avez commencé et m'a ouvert les yeux. Avec vos instructions, j'ai assigné le trou à l'Ellipse.Tag, puis sur la classe Hole, j'ai une référence au HolePattern auquel appartient le Hole. Cela me permet d'escalader l'arbre de trou au besoin. Ce site est génial! – MattSlay

0

Vous lisez probablement déjà ma réponse où je l'avais dit que je travaille. Et cela fonctionne parfaitement, (sauf qu'il nécessite une grande précision avec la souris), mais je veux poser cette question: est-il vraiment intelligent d'ajouter un gestionnaire d'événements à CHAQUE ellipse qui est ajouté à une toile? Maintenant, je ne sais pas quel genre de bog mémoire pourrait être, ou peut-être que c'est un morceau de gâteau pour WPF et Windows à gérer. Dans un cas pratique, je suppose qu'il n'y aurait pas plus de 30-50 trous, même sur un écran qui avait plusieurs modèles, mais quand même; FIFTY gestionnaires d'événements? Cela semble juste effrayant. Et en fait, chaque «trou» est visuellement représenté par deux cercles concentriques et une étiquette de texte (voir le screenhow ici: http://twitpic.com/1f2ci/full), et je sais que l'utilisateur devrait être capable de cliquer sur l'un de ces éléments pour sélectionner un trou. Cela signifie un gestionnaire d'événements sur 3 éléments pour chaque trou. Maintenant, nous pourrions parler de 100 gestionnaires d'événements ou plus.

Il semble qu'il devrait y avoir une solution où vous pourriez avoir un seul gestionnaire d'événements sur le canevas et lire la référence de l'élément sous la souris, puis travailler dessus pour obtenir la propriété .TAG de cet élément, et ainsi de suite .

0

Je pensais poster ma solution finale et plus raffinée au cas où cela aiderait quelqu'un d'autre.

void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    int ClickMargin = 2;// Adjust here as desired. Span is in both directions of selected point. 
    var ClickMarginPointList = new Collection<Point>(); 
    Point ClickedPoint = e.GetPosition(canvas1); 
    Point ClickMarginPoint=new Point(); 
    for (int x = -1 * ClickMargin; x <= ClickMargin; x++) 
    { 
     for (int y = -1 * ClickMargin; y <= ClickMargin; y++) 
     { 
      ClickMarginPoint.X = ClickedPoint.X + x; 
      ClickMarginPoint.Y = ClickedPoint.Y + y; 
      ClickMarginPointList.Add(ClickMarginPoint); 
     } 
    } 

    foreach (Point p in ClickMarginPointList) 
    { 
     HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p); 
     if (SelectedCanvasItem.VisualHit.GetType().BaseType == typeof(Shape)) 
     { 
      var SelectedShapeTag = SelectedCanvasItem.VisualHit.GetValue(Shape.TagProperty); 
      if (SelectedShapeTag!=null && SelectedShapeTag.GetType().BaseType == typeof(Hole)) 
      { 
       Hole SelectedHole = (Hole)SelectedShapeTag; 
       SetActivePattern(SelectedHole.ParentPattern); 
       SelectedHole.ParentPattern.CurrentHole = SelectedHole; 
       return; //Get out, we're done. 
      } 
     } 
    } 
} 
Questions connexes