奇怪的Bug与Cursor.Hide()函数

时间:2016-04-19 13:10:22

标签: c# cursor picturebox

我正在开发一个Battleship Game项目,我创建了一个名为“GraphicCell”的控件,它继承自“PictureBox”类但是作为一个按钮起作用(不希望按钮具有变化的颜色效果)当它盘旋在它上面时。)

我让它为GraphicCell设置一个BackgroudImage并在你悬停时隐藏光标(你可以在GIF中看到)。

我还制作了一个名为“已锁定”的参数,我将其用于播放器的主板,因为它仅用于查看计算机拍摄的位置,无需按下它。 请注意,光标应显示在锁定的光标上。

错误:当我将鼠标悬停在非锁定的GraphicCells上时,光标会像它应该隐藏一样,对于锁定的光标,它会显示它应该如此,但是当我将鼠标悬停在锁定的光标上时,光标将不会当我将鼠标悬停在非锁定状态时隐藏。

GIF例证错误:https://gyazo.com/750a2688a3d33d49462ff6b6e68533d1

(左=未锁定,右=已锁定)

代码(Bug应该在MouseEnterEvent / MouseLeaveEvent functinon中):

  public class GraphicCell : PictureBox
  {
    enum SquareImage {None, Empty, Bombed};
    readonly int x, y;
    readonly Square s;
    bool locked;

    public GraphicCell(int x, int y, Square s, bool locked = false)
    {
        this.x = x;
        this.y = y;
        this.s = s;
        this.locked = locked;
        this.Size = new System.Drawing.Size(25, 25);
        this.BackgroundImageLayout = ImageLayout.Stretch;
        this.SizeMode = PictureBoxSizeMode.StretchImage;
        this.BackgroundImage = Properties.Resources.water;
        this.MouseEnter += new EventHandler(MouseEnterEvent);
        this.MouseLeave += new EventHandler(MouseLeaveEvent);
    }

    public bool Locked { get { return locked; } set { locked = value; } }

    public void Update(Result r)
    {
        if (r != Result.None)
        {
            locked = true;

            switch (r)
            {
                case (Result.Miss):
                    ChangeImage(SquareImage.Empty);
                    break;

                case (Result.Hit):
                case (Result.ShipDestroyed):
                case (Result.Victory):
                    ChangeImage(SquareImage.Bombed);
                    break;
            }
        }
    }

    private void ChangeImage(SquareImage si)
    {
        switch (si)
        {
            case (SquareImage.None):
            this.Image = null;
                break;

            case (SquareImage.Empty):
                    this.Image = Properties.Resources.empty;
                break;

            case (SquareImage.Bombed):
                    this.Image = Properties.Resources.bombed;
                break;
        }
    }

    private void MouseEnterEvent(Object sender, EventArgs e)
    {

        if (!locked)
        {
            this.Image = Properties.Resources.water_bomb;
            Cursor.Hide();
        }
    }

    private void MouseLeaveEvent(Object sender, EventArgs e)
    {
        Cursor.Show();

        if (!locked)
        {
            if (this.Image != null)
                this.Image = null;
        }
    }

    public Square GetSquare()
    { return this.s; }

    public int GetX()
    { return this.x; }

    public int GetY()
    { return this.y; }
}

|

|

编辑:

感谢OldBoyCoder&汉斯帕斯特。 问题是,在MouseLeaveEvent中我连续两次调用“Cursor.Show”函数,如果我转到一个非锁定的函数然后转到一个锁定的函数,然后只调用一次“Cursor.Hide”,这样它就会继续显示

修正:

private void MouseLeaveEvent(Object sender, EventArgs e)
{
    Cursor.Show();

    if (!locked)
    {
        if (this.Image != null)
            this.Image = null;
    }
}

要:

private void MouseLeaveEvent(Object sender, EventArgs e)
{
    if (!locked)
    {
        Cursor.Show();

        if (this.Image != null)
            this.Image = null;
    }
}

3 个答案:

答案 0 :(得分:1)

不完整的答案,因为我还没有解决方案但是必须平衡对Show和Hide的调用,因为有一个内部计数器:

自:

https://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(System.Windows.Forms.Cursor.Hide);k(Hide);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true

必须平衡Show和Hide方法调用。每次调用Hide方法都必须对Show方法进行相应的调用。

你正在制作的所有Show show需要与Hides保持平衡。

答案 1 :(得分:0)

您永远不会在方法

中将锁定设置为false
public void Update(Result r)

答案 2 :(得分:0)

您可以根据需要以任意顺序多次拨打vSetCursor(eCursorOperation.Show)vSetCursor(eCursorOperation.Hide)

enum eCursorOperation
{
    Show,
    Hide
}

// Since the cursor is showing to start with assume the internal counter is set to 1 - fingers crossed
private int GiCursorShowCount = 1; 

private void vSetCursor(eCursorOperation ecYourChoice)
{
    switch (ecYourChoice)
    {
        case eCursorOperation.Show:
            while (GiCursorShowCount < 1)
            {
                Cursor.Show();
                GiCursorShowCount++;
            }
            break;
        case eCursorOperation.Hide:
            while (GiCursorShowCount > 0)
            {
                Cursor.Hide();
                GiCursorShowCount--;
            }
            break;
        default:
            break;
    }
}