我有一个显示Equipments
集合的WPF组件。这些Equipments
中的每一个都包含一个或多个Coordinate
。在我的组件MouseMove
上,调用一个函数来检查鼠标当前是否在任何Coordinate
的任何Equipment
范围内徘徊。如果是,则返回有问题的Equipment
,表示应显示包含Equipment
文本信息的弹出窗口。
除此之外,所有Coordinates
都包含ImageDrawing
,其中显示每个Equipment
的符号(用户将鼠标悬停在符号上以查看文本弹出窗口的符号)。这些被放在一个单独的DrawingGroup
中以加快渲染速度。这样做的另一个好处是,如果要隐藏某些Equipments
,我们只需从Coordinates' ImageDrawing
中移除DrawingGroup
,它们仍将保留在Equipments
列表中(他们应该这样做。)
但是,当鼠标悬停在Coordinate
上时,这不会阻止显示弹出窗口,因为它与DrawingGroup
分开。因此,要检查是否要显示文本弹出窗口,我必须同时检查鼠标是否在任何Coordinate
的范围内,并检查ImageDrawing
是否为Coordinate
在} DrawingGroup
。
关于我的问题(tl; dr):迭代所有这些项目的哪种方式会最快?我有:
List<Equipment> equipments;
对于这些中的每一个(这个列表中的9个中有9个包含一个项目,并且从不超过5个)
List<Coordinate> coordinates;
对于这些Coordinates
中的每一个,我必须检查他们的ImageDrawing
是否在DrawingCollection
(在这种情况下是DrawingGroup.Children
)中,根据到msdn,是ordered collection of Drawing objects.
为此,我从这开始:
foreach (Equipment equipment in equipments)
{
foreach (Coordinate coordinate in equipment.Coordinates)
{
ImageDrawing image = coordinate.ImageDrawing;
if (image != null)
{
if (currentDrawingGroup.Children.Contains(image))
{
if (image.Rect.Bottom > y &&
image.Rect.Top < y &&
image.Rect.Left < x &&
image.Rect.Right > x)
{
return equipment;
}
}
}
}
}
但是认为在隐藏了大量设备的情况下,这会变成许多迭代,并且我可以将其更改为此(因为Children.Contains(image)
无论如何都可以在幕后迭代):
foreach (var child in currentDrawingGroup.Children)
{
foreach (Equipment equipment in equipments)
{
foreach (Coordinate coordinate in equipment.Coordinates)
{
ImageDrawing image = coordinate.ImageDrawing;
if (image != null)
{
if (image == child)
{
if (image.Rect.Bottom > y &&
image.Rect.Top < y &&
image.Rect.Left < x &&
image.Rect.Right > x)
{
return equipment;
}
}
}
}
}
}
我知道这个问题太长了,从长远来看,我在这里看到的优化可能并不重要。但有没有办法可以在循环中没有这么多循环的情况下完成?我觉得应该有一个LINQ表达式帮助我,虽然我不知道其中任何一个是否比foreach循环更快。对事物进行排序的方式(Equipments
通过从DrawingGroup
中删除它们而隐藏它们)是我无法控制的,很难改变。非常感谢。
答案 0 :(得分:1)
如果要隐藏某些设备,让设备自己管理其可见性会不会更清洁?这样你只要先询问设备是否可见,如果没有则跳过它?
因此,您的设备也始终存在,但是可见或不可见,当您将鼠标悬停时,您无需检查坐标是否在DrawingGroup中......它已经为您处理了。
关于迭代vs Contains()
,contains函数是一个线性搜索,因此它与迭代列表相同。