我有一个带有一些Ellipse对象的WPF Canvas(显示为圆圈)。每个圆都来自一个集合类实例,它实际上是一个自定义的孔模式类。每个模式都有一定数量的圆圈,然后使用下面的代码使用集合上的迭代将每个圆圈添加到画布。
因此,画布上填充了一堆圆圈,每个圆圈属于某个模式实例。您可以在此处看到屏幕截图:http://twitpic.com/1f2ci/full
现在我想添加点击画布上的圆圈的功能,并能够确定它所属的集合,这样我就可以对该圆所属的选定图案做更多的工作。< / p>
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);
}
}
}
答案 0 :(得分:3)
所有FrameworkElements
都有Tag
属性,该属性属于object类型,可用于保存任意信息。您可以将HolePattern
分配给Tag
属性,稍后可以轻松使用该属性来获取相关集合。
即:
...
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;
...
}
答案 1 :(得分:0)
所以你可能已经阅读了我的回复,我说我有它的工作。它确实工作得很好(除了鼠标需要很高的精度),但我想问一下:将事件处理程序添加到添加到画布的每个椭圆是否真的很聪明?现在我不知道可能是什么样的内存bog,或者它可能是WPF和Windows处理的一块蛋糕。
在一个实际案例中,我猜即使在具有多种模式的屏幕上,也不会有更多的30-50个洞,但仍然存在; FIFTY 事件处理程序?这看起来很吓人。实际上,每个“洞”在视觉上由两个同心圆和一个文本标签表示(请参见此处的屏幕显示:http://twitpic.com/1f2ci/full),我知道用户希望能够点击其中任何一个元素到选择一个洞。这意味着每个洞的3个元素上的事件处理程序。现在我们可以谈论100个或更多事件处理程序。
似乎应该有一个解决方案,你可以在Canvas上只有一个事件处理程序,并在鼠标下读取元素引用,然后处理它以获取该元素的.Tag属性,依此类推。
答案 2 :(得分: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.
}
}
}
}