トップ回答者
スクロールバーが消えない

質問
-
PanelのAutoScrollプロパティをtrueにして、スクロールバーを表示させています。別のボタンを押すとスクロールバーが無くなるような内容にPanel内を変更しています。
この時、スクロールバーにマウスを重ねるとWindows7では薄い青色に変化し、マウスを外すと青色がフェードアウトして元の色に戻るのですが、フェードアウトが完了する前に素早くスクロールバーを非表示にすると、マウスを重ねていたスクロールバーが見かけ上表示されてしまいます。
OSの設定をクラシック表示にしたり、コントロールパネルの「コンピュータを見やすくします」のところで「必要のないアニメーションは無効にします(可能な場合)」にチェックを入れたりすれば上記の現象は発生しません。
また、Spy++で見るとスクロールバーは無くなっているようです。
十分な時間を空けてから(秒に近いオーダー)Refreshをかけたり、自分で画面の外にウィンドウを移動させてから画面内に戻すと消えます。スクロールバーを消す良い方法はないでしょうか。
.Net 4 Client Profile です。よろしくお願いします。
回答
-
強引ですが、レイアウトの変更後に下記コードを実行するのはいかがでしょうか?
PerformLayout しているのは、スクロールバーが表示された場合のつまみサイズの再計算のためです。
// using System.Reflection; var mi = typeof(Panel).GetMethod("RecreateHandle", BindingFlags.Instance | BindingFlags.NonPublic); if (mi != null) mi.Invoke(panel1, null); panel1.PerformLayout();
- 回答としてマーク iwims 2011年11月9日 3:14
すべての返信
-
レスありがとうございます。
複数の環境で発生するのでスペックのせいでは無いと思いますが。。。
自分の環境はCore i5 M450@2.40GHz NVIDIA GeForce GT 330M です。
再現方法はAutoScrollをtrueにしたPanelをフォームに適当に配置し、その中にスクロールバーが表示されるような位置にLabel等なんでもいいので配置します。
後は適当なButtonのクリックイベントで例えば下記のようにしてスクロールバーの表示、非表示を切り替えれば再現します。
private void button1_Click(object sender, EventArgs e) {
panel1.AutoScroll = !panel1.AutoScroll;
} -
複数の環境で発生するのでスペックのせいでは無いと思いますが。。。
自分の環境はCore i5 M450@2.40GHz NVIDIA GeForce GT 330M です。
再現方法はAutoScrollをtrueにしたPanelをフォームに適当に配置し、その中にスクロールバーが表示されるような位置にLabel等なんでもいいので配置します。
後は適当なButtonのクリックイベントで例えば下記のようにしてスクロールバーの表示、非表示を切り替えれば再現します。
private void button1_Click(object sender, EventArgs e) {
panel1.AutoScroll = !panel1.AutoScroll;
}
試してみました。Windows 7 64bit SP1・Core i7-2600 3.40GHz・メモリ12.0GB・GeForce GT 530
・・・こちらでも再現しますね (^^;
いろいろ試してみましたが、どうにも厄介な現象のようです。フィードバックに報告しといた方がいいかもしれません。
https://connect.microsoft.com/VisualStudio/content/content.aspx?ContentID=25941
# ちなみに旧日本語版フィードバックは暫定的に見れるようになったみたいです。
# https://connect.microsoft.com/site550
ひらぽん http://d.hatena.ne.jp/hilapon/ -
とりあえず回避はできるんじゃないかなぁ
bool hVisible; bool vVisible; hVisible = panel1.HorizontalScroll.Visible; vVisible=panel1.VerticalScroll.Visible; panel1.VerticalScroll.Visible = false; panel1.HorizontalScroll.Visible = false; panel1.AutoScroll = !panel1.AutoScroll; panel1.VerticalScroll.Visible = vVisible; panel1.HorizontalScroll.Visible = hVisible;
エフェクトの描画でWM_TIMERが飛んできてるのを無駄に反応して描画しちゃってるみたいですね。
スクロールバーが表示されている状態だとエフェクトが発動するので、スクロールバーを一時的に消してからAutoScrollを変更すればエフェクトを描画することがなくなるので、この現象は回避できそうです。#他にも同じ原因の描画ミスはありそう
追記:
Visibleにfalseを入れなくてもAutoScroll変更後に変更前のVisibleを戻すだけでよさそう。
動作検証 Vista 32bitデスクトップ + 7 64bitノート
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)- 編集済み gekkaMVP 2011年11月7日 13:34
-
とりあえず回避はできるんじゃないかなぁ
・・・・(中略)・・・・・
スクロールバーが表示されている状態だとエフェクトが発動するので、スクロールバーを一時的に消してからAutoScrollを変更すればエフェクトを描画することがなくなるので、この現象は回避できそうです。
同様の手段は試してみましたが、残念ながらこちらの環境ではうまくいかないですね。上記コードも試してみましたが、AutoScroll が true のままか、もしくは false にしても描画が残ったままです。
そもそもこんな対処せねばならない時点で、十分フィードバック行きだと思う(汗
ひらぽん http://d.hatena.ne.jp/hilapon/ -
強引ですが、レイアウトの変更後に下記コードを実行するのはいかがでしょうか?
PerformLayout しているのは、スクロールバーが表示された場合のつまみサイズの再計算のためです。
// using System.Reflection; var mi = typeof(Panel).GetMethod("RecreateHandle", BindingFlags.Instance | BindingFlags.NonPublic); if (mi != null) mi.Invoke(panel1, null); panel1.PerformLayout();
- 回答としてマーク iwims 2011年11月9日 3:14
-
いろいろ試してみましたが、どうにも厄介な現象のようです。フィードバックに報告しといた方がいいかもしれません。
https://connect.microsoft.com/VisualStudio/content/content.aspx?ContentID=25941
Not Found になります。こちらでよろしいでしょうか?Visual Studio Feedback
それとも、フィードバックに投稿した内容?
Jitta@わんくま同盟- 編集済み Jitta 2011年11月7日 11:52 変換ミス(--;
-
いろいろ試してみましたが、どうにも厄介な現象のようです。フィードバックに報告しといた方がいいかもしれません。
https://connect.microsoft.com/VisualStudio/content/content.aspx?ContentID=25941
Not Found になります。こちらでよろしいでしょうか?Visual Studio Feedback
それとも、フィードバックに投稿した内容?
英語版のサイトで報告するしかなさそうですね。
https://connect.microsoft.com/site550
には
「日本語 Visual Studio フィードバックのホームページはこちらに移動しました。新しいフィードバックはこちらから送信してください」
と書いてあるのに・・・ダメじゃん(汗
ひらぽん http://d.hatena.ne.jp/hilapon/