3

对于我的一生,我无法理解为什么这段代码会产生以下输出......

我认为如果类型公开了 Rectangle 属性并且您使用了矩形对象的 Contains 方法,则在使用 List 和 lambda 时存在错误或某些东西......并且当 List Find 方法失​​败时显式迭代证明是正确的......

单程

代码

public GridSquare WorldToKeyPadSub(Point location)
    {
        location = _Map.WorldToClient(location);
        GridSquare gs = this.Find(x => x.Rectangle.Contains(location));
        GridSquare kp = gs.Find(x => x.Rectangle.Contains(location));
        List<GridSquare> list = kp.FindAll(x=>x.Rectangle.Contains(location));
        u.dp(list.Count);
        GridSquare sub = kp.Find(x => x.Rectangle.Contains(location));

        if (sub == null)
        {
            u.dp("Location to look for " + location);
            u.dp("Found Location in grid square " + gs.ToString());
            u.dp("grid square bounds " + gs.Rectangle.ToString());
            u.dp("Found Location in Keypad " + kp.ToString());
            u.dp("key pad bounds " + kp.Rectangle.ToString());
            u.dp("Sub Key Pads Print All sub keys in this grid.keypad");
            foreach (GridSquare t in kp)
            {
                u.dp(t.ToString() + "  " + t.Rectangle.ToString());                   

            }
            u.dp("Sub Key Pads Print Explicit Finds");
            foreach (GridSquare t in kp)
            {
                if (location.X >= t.Location.X
                    && location.Y >= t.Location.Y
                    && location.X <= t.Location.X + t.Rectangle.Width
                    && location.Y <= t.Location.Y + t.Rectangle.Height)
                {
                    u.dp(true);
                    u.dp(t.ToString() + "  " + t.Rectangle.ToString());
                }

            }
        }
        return sub;
    }

这会产生以下输出...

请注意显式矩形(又名手动方法)如何找到包含该位置的网格正方形......内部 GDI 版本失败......

Location to look for {X=1476,Y=1716}
Found Location in grid square GS: 14.3.0.0
grid square bounds {X=1398,Y=1650,Width=100,Height=100}
Found Location in Keypad GS: 14.3.6.0
key pad bounds {X=1465,Y=1683,Width=33,Height=34}
Sub Key Pads Print All sub keys in this grid.keypad
GS: 14.3.6.7  {X=1465,Y=1683,Width=11,Height=11}
GS: 14.3.6.8  {X=1476,Y=1683,Width=11,Height=11}
GS: 14.3.6.9  {X=1487,Y=1683,Width=11,Height=11}
GS: 14.3.6.4  {X=1465,Y=1694,Width=11,Height=11}
GS: 14.3.6.5  {X=1476,Y=1694,Width=11,Height=11}
GS: 14.3.6.6  {X=1487,Y=1694,Width=11,Height=11}
GS: 14.3.6.1  {X=1465,Y=1705,Width=11,Height=11}
GS: 14.3.6.2  {X=1476,Y=1705,Width=11,Height=11}
GS: 14.3.6.3  {X=1487,Y=1705,Width=11,Height=11}
Sub Key Pads Print Explicit Finds
True
GS: 14.3.6.1  {X=1465,Y=1705,Width=11,Height=11}
True
GS: 14.3.6.2  {X=1476,Y=1705,Width=11,Height=11}
A first chance exception of type 'System.NullReferenceException'
4

3 回答 3

6

Rectangle.Contains(Point)在矩形的上限上是排他的(严格小于)。

例如,Rectangle.Contains(Point)在您的上下文中执行的等效检查将是:

foreach (GridSquare t in kp) 
{ 
    if (location.X >= t.Location.X 
        && location.Y >= t.Location.Y 
        && location.X < t.Location.X + t.Rectangle.Width   // < instead of <=
        && location.Y < t.Location.Y + t.Rectangle.Height) // < instead of <=
    { 
        u.dp(true); 
        u.dp(t.ToString() + "  " + t.Rectangle.ToString()); 
    } 

} 

如您所见,它将上限验证为严格小于,而不是小于或等于您的方法与该方法之间的差异Rectangle.Contains(Point)

在您的示例中传递的位置是 {X=1476,Y=1716},当传递给这些矩形的包含时:

GS: 14.3.6.1  {X=1465,Y=1705,Width=11,Height=11}  
GS: 14.3.6.2  {X=1476,Y=1705,Width=11,Height=11}  

将返回 false,当您的返回 true 时。

这就是为什么kp.Find(x => x.Rectangle.Contains(location));返回 null,但您的手动检查返回 true。

于 2010-02-04T05:45:53.760 回答
2

这是我发现的...

考虑一下定义为 0,0,100,100 的矩形......

有人会假设点 100,100 在该矩形内,但事实并非如此......

Rectangle.Contains 不包括边界...换句话说,它只会对定义为 0,0,100,100 的矩形中的所有点 0,0 到 99,99 返回 true ...

我遇到的麻烦是,当您使用 GDI 绘制该矩形时……像素被绘制为向下和向右偏移……

最终效果是 Rectangle.Contains 包含矩形的顶部和左腿,不包括矩形的底部和右腿......从图形的角度来看......你可以放大到像素级别在用鼠标进行命中测试时...

光标可能看起来就在矩形边界的右下方...但是由于 Rectangle 的专有性质,命中测试返回 false。包含右腿和下腿...

西南

于 2010-02-10T23:30:20.067 回答
0

我看到你可以检查两件事:

  1. 您的明确检查是包容性的 - 小于等于,大于等于。如果 Rectangle.Contains 是独占的,那么您的显式检查发现的两个点都将被省略。

  2. 您确定 x.Location.X 和 .Y 始终与 x.Rectangle.X 和 .Y 相同吗?

于 2010-02-04T05:49:18.103 回答