0

我有一个 WPF 画布,上面有一些椭圆对象(显示为圆圈)。每个圆圈都来自一个集合类实例,它实际上是一个自定义孔模式类。每个图案都有一定数量的圆圈,然后使用下面的代码对集合进行迭代,将每个圆圈添加到画布中。

因此,画布上填充了一堆圆圈,每个圆圈都属于某个模式实例。你可以在这里看到截图:http: //twitpic.com/1f2ci/full

现在我想添加在画布上单击一个圆圈的功能,并能够确定它所属的集合,这样我就可以对该圆圈所属的选定图案做更多的工作。

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);
        }
    }
}
4

3 回答 3

3

它们都有FrameworkElements一个Tag对象类型的属性,可用于保存任意信息。您可以将 分配HolePattern给该Tag属性并在以后轻松使用它来获取关联的集合。

IE:

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

稍后在点击事件中:

event(object sender,....)
{
   Ellipse e = sender as Ellipse;
   HolePattern hp = e.Tag as HolePattern;
   ...
}
于 2009-02-23T22:33:29.153 回答
0

所以你可能已经阅读了我的回复,我说我已经成功了。它确实工作得很好,(除了它需要非常精确的鼠标),但我想问这个:为每个添加到画布的椭圆添加事件处理程序真的很聪明吗?现在我不知道这可能是什么样的内存沼泽,或者它可能是 WPF 和 Windows 处理的小菜一碟。

在实际情况下,我猜即使在具有多个图案的屏幕上也不会超过 30-50 个孔,但仍然; 五十个事件处理程序?只是看起来很吓人。实际上,每个“洞”都由两个同心圆和一个文本标签在视觉上表示(参见此处的屏幕显示:http: //twitpic.com/1f2ci/full),我知道用户希望能够点击这些元素中的任何一个来选择一个孔。这意味着每个洞都有 3 个元素的事件处理程序。现在我们可以谈论 100 个或更多的事件处理程序。

似乎应该有一个解决方案,您可以在 Canvas 上只有一个事件处理程序并读取鼠标下的元素引用,然后处理它以获得该元素的 .Tag 属性,依此类推。

于 2009-02-24T06:11:41.457 回答
0

我想我会发布我的最终和更完善的解决方案,以防它帮助其他人。

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.
            }
        }
    }
}
于 2009-02-24T20:18:58.707 回答