みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C# MouseHoverを何度も呼ぶには

C# MouseHoverを何度も呼ぶには

いつもお世話になっています
只今、PictureBoxに複数の絵(四角などの図形)を描画し
各図形にマウスを持って行ったときにToolTipを表示するプログラムを作成しているのですが、うまくいきません。

マウスを動かして、ある図形で止まったらToolTipを表示するという処理にしたいのですが
PictureBoxにマウスが入ってから出るまでの間、MouseHoverが1度しか呼ばれません。
これでは、使い勝手が悪すぎるので何とかしてマウスが止まるたびにToolTipを表示したいのです。

MouseHover内では、マウスの位置からどの図形の上にマウスがあるかチェックし
図形別に用意してある文字を表示しています。
toolTip1.SetToolTip(pictureBox1, "文字列");
toolTip1.Active = true;

代替案などでもかまいませんので
どなたか分かる方がいましたらお願いします。

OS:Vista
環境:VisualStudio2008
言語:C#

投稿日時 - 2010-04-05 17:33:55

QNo.5804638

すぐに回答ほしいです

質問者が選んだベストアンサー

代替案でもいいのなら、以下の感じでどうでしょう?

public partial class Form1 : Form
{
private Rectangle m_rectTest1 = new Rectangle(10, 10, 50, 50);
private Rectangle m_rectTest2 = new Rectangle(60, 60, 50, 50);
private Rectangle m_rectNow;
private ToolTip m_toolTip = new ToolTip();

public Form1()
{
InitializeComponent();

m_toolTip.AutoPopDelay = 5000;
m_toolTip.InitialDelay = 1000;
m_toolTip.ReshowDelay = 500;
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (m_rectTest1.Contains(e.Location))
{
if (m_rectNow != m_rectTest1)
{
m_rectNow = m_rectTest1;
m_toolTip.SetToolTip(this.pictureBox1, "てすと1");
}
}
else if (m_rectTest2.Contains(e.Location))
{
if (m_rectNow != m_rectTest2)
{
m_rectNow = m_rectTest2;
m_toolTip.SetToolTip(this.pictureBox1, "てすと2");
}
}
else
{
m_rectNow = Rectangle.Empty;
m_toolTip.SetToolTip(this.pictureBox1, "");
}
}

private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
m_rectNow = Rectangle.Empty;
m_toolTip.SetToolTip(this.pictureBox1, "");
}
}

参考くらいにはなると思います。

投稿日時 - 2010-04-06 12:15:45

お礼

回答ありがとうございます。
試してみたところ、かなりいい具合に動きました。
何とかなりそうです。
ありがとうございました。

投稿日時 - 2010-04-07 18:02:21

このQ&Aは役に立ちましたか?

3人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

こんにちは。

乗せて頂いたコードを実行したところ確かにMouseHoverは1度だけですね・・・
このような物はやはりPictureBoxを複数貼り付けるのが正攻法です。課題などで作っている場合はしかたがありませんが・・・

下記に自分が実験用で作ったサンプルを乗せます。実験用なのでRectangleに値を格納しておりません。あくまでもMouseHoverの動作の為に作製したプログラムなので・・・

Rectangle rect = new Rectangle(0, 0, 50, 50);
Point mPoint = new Point(0, 0);
Graphics graph;
Bitmap bitmap;

private void Form1_Load(object sender, EventArgs e)
{
paint();

}

private void pictureBox1_MouseHover(object sender, EventArgs e)
{

if (mPoint.X <= 50)
{

if (mPoint.Y < 50)
{
toolTip1.SetToolTip(pictureBox1, "SkyBlue");
toolTip1.Active = true;
}
else
{

toolTip1.SetToolTip(pictureBox1, "LightGreen");
toolTip1.Active = true;

}

}
else
{
if (mPoint.Y < 50)
{
toolTip1.SetToolTip(pictureBox1, "Blue");
toolTip1.Active = true;
}
else
{

toolTip1.SetToolTip(pictureBox1, "Green");
toolTip1.Active = true;

}

}


}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
mPoint = new Point(e.X, e.Y);
pictureBox1_MouseHover(null, EventArgs.Empty);


}

void paint()
{
bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
graph = Graphics.FromImage(bitmap);

graph.FillRectangle(Brushes.SkyBlue, rect);

rect.Offset(50, 0);
graph.FillRectangle(Brushes.Blue, rect);

rect.Offset(-50, 50);
graph.FillRectangle(Brushes.LightGreen, rect);

rect.Offset(50, 0);
graph.FillRectangle(Brushes.Green, rect);

pictureBox1.Image = bitmap;

}

private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
toolTip1.Active = false;
}
}




pictureBox1_MouseHover(null, EventArgs.Empty);
この一文は無理やりMouseHoverを動かしています。サンプルなのでこの書き方をしていますが好ましくない書き方です。
イベントハンドラは通常、それを登録したオブジェクトのイベントに対して何らかの処理を行うことが目的のメソッドなので、それ以外の目的でそのメソッドを実行するのはあまりいいとは言えません。

この一文を外すとMouseHoverは1度しか(正しくはPictureBox上にMouseが乗った1回だけしか)動きませんでした。
但しこの一文を入れると図形に載っている間常にでてしまうので求めている動作とは違うと思います。
ご参考までに・・・

投稿日時 - 2010-04-07 12:51:04

お礼

何度もありがとうございます。
試してみたところ、やりたいことが実現できました。
ですが、図形上にいる間ずっと表示されるうえに、環境によってはチカチカと点滅してしまったので、実用化は却下されてしまいました・・・
でも、何度も答えてくださり嬉しかったです。
ありがとうございます。

投稿日時 - 2010-04-07 18:00:36

ANo.2

>各図形の位置を示すRectangleをもつ自作クラスを配列で持っており
ソースを見せていただきませんか?
私が書くと全て書き直さなければいけなくなりそうなので

投稿日時 - 2010-04-06 11:17:04

補足

こんな感じです。
Form1にPictureBox1がのってます。

public partial class Form1 : Form
{
  Bitmap bitmap;
  Graphics graph;
  ToolTip tip = new ToolTip();
  Point mousePoint;
  myRect[] listRect = new myRect[3];

  private void Form1_Load(object sender, EventArgs e)
  {
    pictureBox1.MouseMove += new MouseEventHandler(pictureBox1_MouseMove);
    pictureBox1.MouseHover += new EventHandler(pictureBox1_MouseHover);
    pictureBox1.MouseLeave += new EventHandler(pictureBox1_MouseLeave);
    tip.Active = false;
    init();
  }

  void init()
  {
    for (int i = 0, cnt = listRect.Length; i < cnt; i++)
      listRect[i] = new myRect("図形" + (i + 1));

    bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
    graph = Graphics.FromImage(bitmap);

    paint();
  }

  void paint()
  {
    for (int i = 0, cnt = listRect.Length; i < cnt; i++)
    {
      Rectangle rect = new Rectangle(10 + i * 30, 20, 20, 20);
      graph.FillRectangle(new SolidBrush(Color.Blue), rect);
      listRect[i].Rect = rect;
    }
    pictureBox1.Image = bitmap;
  }

  void pictureBox1_MouseLeave(object sender, EventArgs e)
  {
    tip.Active = false;
  }

  void pictureBox1_MouseHover(object sender, EventArgs e)
  {
    myRect tmp = search(mousePoint);
    if (tmp == null)
      return;
    if (!tip.Active)
    {
      tip.SetToolTip(pictureBox1, tmp.Txt);
      tip.Active = true;
    }
  }

  //マウス位置に図形がないかチェック
  myRect search(Point p)
  {
    for (int i = 0, cnt = listRect.Length; i < cnt; i++)
    {
      if (listRect[i].Rect.X <= p.X && p.X <= listRect[i].Rect.Right &&
        listRect[i].Rect.Y <= p.Y && p.Y <= listRect[i].Rect.Bottom)
      {
        return listRect[i];
      }
    }
    return null;
  }

  void pictureBox1_MouseMove(object sender, MouseEventArgs e)
  {
    mousePoint = new Point(e.X, e.Y);
  }
}

//自作図形クラス
class myRect
{
  string text = "";
  public Rectangle Rect { set; get; }
  public string Txt
  {
    get { return text; }
  }

  public myRect(string txt)
  {
    text = txt;
  }
}

投稿日時 - 2010-04-06 16:29:18

ANo.1

おはようございます。

ほかの処理がどのようになっているか分かりませんが記述してある感じで書いてみました。
結果としてはきちんと出来ています。

private void Form1_Load(object sender, EventArgs e)
{
toolTip1.SetToolTip(pictureBox1, "pic1");
toolTip1.SetToolTip(pictureBox2, "pic2");
toolTip1.SetToolTip(pictureBox3, "pic3");
toolTip1.SetToolTip(pictureBox4, "pic4");

pictureBox2.MouseHover += new EventHandler(pictureBox1_MouseHover);
pictureBox3.MouseHover += new EventHandler(pictureBox1_MouseHover);
pictureBox4.MouseHover += new EventHandler(pictureBox1_MouseHover);
}

private void pictureBox1_MouseHover(object sender, EventArgs e)
{
toolTip1.Active = true;
}


以上です。

投稿日時 - 2010-04-06 10:27:18

お礼

回答ありがとうございます。

確かにこれだとうまくいきそうですが
すみません、言葉が足りませんでした。
PictureBoxは一つしかなく、図形は一つのPictureBoxにすべて描画されていて
各図形の位置を示すRectangleをもつ自作クラスを配列で持っており
MouseHoverイベント時にマウスの位置からどの図形にあるかをRectangleを利用して調べ、それに合わせた文字列(これも自作クラスに保持されている)をToolTipに表示するようにしたいのです。

何か良い方法がありましたらお願いします。

投稿日時 - 2010-04-06 10:38:08

あなたにオススメの質問