2016-04-19 13 views
0

私は戦艦ゲームプロジェクトに取り組んでおり、 "PictureBox"クラスを継承するが、ボタンとして機能している "GraphicCell"という名前のコントロールを作った。ボード上にホバーしたときにボタンが持つ色の効果が変化します)。Cursor.Hide()関数で奇妙なバグ

GraphicCellのBackgroudImageを設定し、カーソルを置いたときにカーソルを隠すようにしました(GIFで見ることができます)。

私はプレーヤーのボードに使用しているパラメータ「locked」を作成しました。これは、コンピュータが撮影した場所を表示するためのものであり、押す必要はないからです。 ロックされているものにカーソルが表示されることに注意してください。

バグ:ロックされていないGraphicCellにカーソルを合わせると、カーソルが隠れて表示されているように表示されます。表示されているように表示されますが、私がロックされていないものの上を動かすと、もはや。 https://gyazo.com/750a2688a3d33d49462ff6b6e68533d1

(左=ロック=、右ロックされていない)

コード(バグが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; } 
} 

バグの

GIFのexemple |

|

編集:OldBoyCoder &ハンスアンパッサンへ

問題を修正感謝。 問題はMouseLeaveEventで、私は非ロックの1つに移動してロックされたものに移動し、次に「Cursor.Hide」を1回だけ呼び出すと、「Cursor.Show」関数を2回連続して呼び出す表示します。

修正:

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; 
    } 
} 
+0

バグが多いので、Show()呼び出しの数はHide()呼び出しの数と等しくなければなりません。それは内部的に単純なカウンタを使用します。バグは、あなたがHide()を呼び出していなくてもShow()を呼び出すことです。したがって、内部カウントは2になります。次回は間違っています.Height()を呼び出すと、カーソルが1になっているのでカーソルが隠されません。コントロールを使用する方がはるかに簡単です。Cursorプロパティを使用して、空のカーソルをプロジェクトに追加します。 –

答えて

1

ない完全な解答方法に戻っfalseにロックされた設定はありませんまだ表示と非表示への呼び出しは、内部カウンタがあるので均衡する必要があります:

表示と非表示メソッド呼び出しがバランスをとらなければならない

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

:から

。 Hideメソッドを呼び出すたびに、対応するShowメソッドの呼び出しが必要です。

これらのすべては、あなたがHidesとバランスを取る必要があることを示しています。

+0

はい、それは「ショー」という行と「隠す」問題があったようです。ありがとう! –

0

私は解決策を持っていないとして、あなたは

public void Update(Result r) 
+0

この関数は、コントロールがクリックされたとき(コードはフォームのコード上にある)にのみ呼び出されます。 この不具合は、GraphicCellsの上にマウスカーソルを置いたときに発生するので、この機能は一度も呼び出されませんでした。 –

関連する問題