DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ListViewSubItem上のToolTipの動作

環境/言語:[C#]
分類:[.NET]

実現したいこと
1.ListViewのサブアイテムごとにツールチップを表示する
2.同じサブアイテムにマウスがある間は
  マウスを動かしてもツールチップを表示したままにする


1については、こちらの記事を参考に実装できました。
http://dobon.net/vb/bbs/log3-38/23463.html

しかし、同じサブアイテムの中でマウスを動かしたときに、
ツールチップが表示されたり消えたりを繰り返してしまうことがわかりました。
マウスが少し揺れるたびにツールチップがチラついてしまうため
なんとか改善したいと思っています。

試しにListViewのMouseMoveイベントに下記だけ書いてみたところ、
ListView上(ListViewItemがない場所)ではいくらマウスを動かしても
常にツールチップが表示されたままでしたが、
ListViewItem上でマウスを動かすと
ツールチップが表示されたり消えたりを繰り返すようになりました。

private void listView1_MouseMove(object sender, MouseEventArgs e)
{
toolTip1.SetToolTip(listView1, "test");
}

恐らくListViewないしListViewItem自体に実装されているツールチップ機能と、
ToolTipコンポーネントが干渉しているような気がします。
この問題の回避策をお持ちの方がいらっしゃいましたらお知恵を貸していただけないでしょうか。
■No29470に返信(ななさんの記事)

mousemoveで前回と同じ条件ならToolTipを更新しない。
MouseのあるListViewItemが同じであれば更新しないなど。
> mousemoveで前回と同じ条件ならToolTipを更新しない。
> MouseのあるListViewItemが同じであれば更新しないなど。

こういうことでしょうか。

private ListViewItem.ListViewSubItem pre;
private void listView_MouseMove(object sender, MouseEventArgs e)
{
  ListViewItem.ListViewSubItem sub = listView.HitTest(listView.PointToClient(Control.MousePosition)).SubItem;
  if (sub != pre)
  {
    toolTip.Active = false;
    if (sub != null && sub.Tag != null)
    {
      toolTip.SetToolTip(listView, sub.Tag.ToString());
      toolTip.Active = true;
    }
    pre = sub;
  }
}

上記は現在のコードほぼそのままなのですが、
サブアイテム内でのマウス操作でツールチップのちらつきが出ます。
何か勘違いしていたら申し訳ありませんがご指摘願います。
■No29476に返信(ななさんの記事)

提示されたコードで試してみましたがこちらでは
特にちらつきはありませんでした。最初のコードは確かにちらつきました。
他の部分でリストビューの内容を書き換えていたりツールチップを書き換えていたりとかはしていませんか?
検証していただきありがとうございます。
改善する見込みがあるとわかって希望が見えてきました。

> 他の部分でリストビューの内容を書き換えていたりツールチップを書き換えていたりとかはしていませんか?

FormLoad時にListVeiwItemを作成して、
後はListViewのMouseMoveイベントでツールチップの処理をしているだけのはずです。

見落としがあるかもしれませんので、少し長いですが他の部分も載せます。
ほぼデフォルトのままですが、ListView.ViewをDetails、FullRowSelectをtrueにしています。
他にListView.ShowItemToolTipsや、ListViewItem.ToolTipTextプロパティも関係していそうなので、
組み合わせを変えて試行錯誤しているのですが改善に至っていません。


********** Code Start **********
// コンストラクタ
public Form1()
{
  InitializeComponent();
}
// ロードイベント
private void Form1_Load(object sender, EventArgs e)
{
  ListViewItem lvi = new ListViewItem(new string[] { "テスト1", "テスト2" });
  lvi.SubItems[0].Tag = "てすと1";
  lvi.SubItems[1].Tag = "てすと2";
  listView.Items.Add(lvi);
}
// マウスムーブイベント
private ListViewItem.ListViewSubItem pre;
private void listView_MouseMove(object sender, MouseEventArgs e)
{
  // 前回投稿時のコード
}

// デザイナで生成されたコード
private void InitializeComponent()
{
  this.components = new System.ComponentModel.Container();
  this.toolTip = new System.Windows.Forms.ToolTip(this.components);
  this.listView = new System.Windows.Forms.ListView();
  this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
  this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
  this.SuspendLayout();
  //
  // listView
  //
  this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
  this.columnHeader1,
  this.columnHeader2});
  this.listView.Dock = System.Windows.Forms.DockStyle.Fill;
  this.listView.FullRowSelect = true;
  this.listView.Location = new System.Drawing.Point(0, 0);
  this.listView.Name = "listView";
  this.listView.Size = new System.Drawing.Size(292, 266);
  this.listView.TabIndex = 0;
  this.listView.UseCompatibleStateImageBehavior = false;
  this.listView.View = System.Windows.Forms.View.Details;
  this.listView.MouseMove += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseMove);
  //
  // Form1
  //
  this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
  this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  this.ClientSize = new System.Drawing.Size(292, 266);
  this.Controls.Add(this.listView);
  this.Name = "Form1";
  this.Text = "Form1";
  this.Load += new System.EventHandler(this.Form1_Load);
  this.ResumeLayout(false);
}
********** Code End **********
■No29479に返信(ななさんの記事)

VS2008でコンパイルしたら再現しました。
VS2010でもFramework3.5に変更したら再現しました。

ということでFramework3.5までだと簡単な解決は難しいと思います。
環境でしたか。盲点でした。
仰るとおりこちらの環境はVS2008+Framework3.5でした。
ちらつきが出なかったのはVS2010+Framework4.0ということでしょうか?

前回投稿後もプロパティの組み合わせを変えてみたり、
ListView.ItemMouseHoverイベントを使用してみたり、
タイマーでインターバルを挟んだりと小細工を弄してみたものの
やはりVS2008+Framework3.5環境での改善は難しそうです。

後は、試していませんがこちらで紹介されている
Helpクラスで代用するくらいでしょうか。
http://dobon.net/vb/dotnet/control/showtooltip.html

ただ、フォームが非アクティブになってしまうのはあまり好ましくないので、
環境をアップする方向で検討したいと考えています。


>shuさん
申し訳ありませんが手元ですぐに環境が用意できないので、
ちらつきが出なかった環境だけ教えていただけますでしょうか。
その後解決済みとさせて頂きます。
■No29500に返信(ななさんの記事)

> >shuさん
> 申し訳ありませんが手元ですぐに環境が用意できないので、
> ちらつきが出なかった環境だけ教えていただけますでしょうか。
> その後解決済みとさせて頂きます。
VS2010+Framework4.0です。
Windows7でもXP(Virtualでコンパイル済みExeを実行)でも状況は変わりありませんでした。
ありがとうございます。
恐らく一人では解決に至らなかった内容でしたので大変助かりました。
また何かありましたらよろしくお願いします。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板