如何使用linq获取数组中控件的最低位置

时间:2016-05-06 10:17:44

标签: .net vb.net linq

如何使用linq

获取数组中控件的最低位置

我有一系列控件说 dim oClipboard()作为控件

我需要具有最低位置或最低位置值的控件来自于oclipboard

到目前为止,我已尝试使用min函数的linq

Dim p = c.Select(Function(g) g.Location).Min.ToString
Dim x = c.Select(Function(g) g).Min(Function(h) h.Location)

以上两个都给出了我在下面说明的错误

System.ArgumentException was unhandled
HResult=-2147024809
Message=At least one object must implement IComparable.
Source=mscorlib
StackTrace:
at System.Collections.Comparer.Compare(Object a, Object b)
at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
at System.Linq.Enumerable.Min[TSource](IEnumerable`1 source)
at System.Linq.Enumerable.Min[TSource,TResult](IEnumerable`1 source, Func`2 selector)

有什么方法可以控制哪个位置最低

2 个答案:

答案 0 :(得分:1)

Point没有实现IComparable。你想如何比较两点?

您可以提供自定义IEqualityComparer<Point>并将实例传递给MinMax。如果您只对X-Coordinate感兴趣,例如您也可以使用:

Dim pxMin As Int32 = c.Select(Function(g) g.Location.X).Min() 

如果您想要控件,可以使用匿名类型使用此方法:

Dim controlPoints = From c in Me.Controls.Cast(Of Control)() 
                    Select controlLoc = New With { .Control = c, .Location = c.Location }
                    Order by controlLoc.Location.X , controlLoc.Location.Y 
Dim minLocControl As Control = controlPoints.First().Control

如果您想处理两个控件可能具有重叠位置的情况:

Dim orderedControlPointGroups =
    From c In Me.Controls.Cast(Of Control)()
    Order By c.Location.X, c.Location.Y
    Group By c.Location Into controlGroups = Group

Dim minLocControlGroup = orderedControlPointGroups.First()
Dim minLocation as Point = minLocControlGroup.Location 
Dim allMinControls as IEnumerable(of Control) = minLocControlGroup.controlGroups 

答案 1 :(得分:1)

如果通过最低位置,则表示控制器与(0,0)点之间的欧几里德距离最短,您可以使用Aggregate扩展方法:

droppable: true

或者如果您只想找到Y坐标最小的控件:

Control[] oClipboard = ...;
Control control = oClipboard.Aggregate((curMin, c) => (curMin == null || Math.Sqrt(c.Location.X * c.Location.X + c.Location.Y * c.Location.Y) < Math.Sqrt(curMin.Location.X * curMin.Location.X + curMin.Location.Y * curMin.Location.Y) ? c : curMin));

现在,作为练习的所有内容都是将其转换为VB.NET。