- PR -

C# Tabコントロール上のDataGridViewが崩れる

1
投稿者投稿内容
ひろし
ぬし
会議室デビュー日: 2002/09/16
投稿数: 390
お住まい・勤務地: 兵庫県
投稿日時: 2008-09-09 21:14
tabコントロールにDataGridViewを貼り付けたところ、
tabページを切り替えると、DataGridView内部の表示が崩れます。
DataGridViewのDataSourceはDataBindingSource経由でDataSetを
参照していることに関係しているのでしょうか?
原因が分かりません。よろしくお願いします。

再現手順
1.tabコントロールの複数PageにDataGridViewを張り付ける。
2.DataGridViewのDataSourceにDataSet格納されたDataTableを参照させる。
(DataBindingSource)
3.tabページを切り替えるとDataGridView内部の表示が崩れる。

症状
1.DataGridViewの内部(実データの部分)の再描画が正しく行われていない。
2.DataGridViewの列名の表示は正しく行われている。
3.DataGridView以外のコントロール(TextBoxやLabel等)は正しく表示される。
4.DataSourceを一旦無参照にし、IDEからDataTableを再Bindingしても改善されない。
5.再描画されることもあるし、ずっと再描画しれくれないこともある。
6.DataSetのデータ自体は整合性を保った状態である。(壊れている形跡は無い)
7.VistaのAeroにしても改善されない。

環境
WindowsVista + .NET Framework3.5 C# (RAM 4GB)

カドルドエグ
常連さん
会議室デビュー日: 2008/05/29
投稿数: 25
投稿日時: 2008-09-10 09:20
「再描画されない」「崩れている」とは、具体的にはどのような状態なのでしょうか?(データがあるのに表示上はデータが0件、など)

それがはっきりしないので確実な方法はなんともいえませんが、
ただ、.NET 2.0の段階でTabControlとDataGridViewの組み合わせでバグらしきものが出る
ことは以前経験したことがあります。

そのときは、Loadイベントで全てのTabPageのVisibleをTrueにする処理を加えることで回避できました。

コード例↓
foreach (TabPage tpg in new TabPage[] { tpg1,tpg2,tpg3,tpg4,tpg5})
{
tpg.Visible = true;
}

理由はまだこちらではわかっていませんが、一度でも「表示された」状態にしないと正常に動かないことがあるようです。
ひろし
ぬし
会議室デビュー日: 2002/09/16
投稿数: 390
お住まい・勤務地: 兵庫県
投稿日時: 2008-09-10 16:07
ご回答ありがとうございます。

症状は下記のとおりでした
別のTabPageの画面の一部がDataGridViewのセルにずっと描画されたままになっていました。例えば隣のPageのPictureBoxの断片が残ったままになります。

DataGridViewのDataSource→BindingSource→DataSetのDataTable
の参照でDataGridViewを再作成したところ(なぜか)解決しました。

試した内容
(1)BindingSourceを再作成→効果なし
(2)TabPageのEnterイベントにReflesh()を追加→効果なし
(3)上記の(1)+(2)→効果なし
(4)DataGridViewの再作成→解決

以前のDataGridViewのプロパティに不適切な設定があったのかも知れません。あるいは、現在は.NET 3.5の環境で開発していますが.NET 2.0時代に作成したものだったのでご指摘のバグが関係しているのでしょうか。

追記
TabPageの再描画Visible()ではなくReflesh()が正しいような気がしますがいかがでしょうか?
カドルドエグ
常連さん
会議室デビュー日: 2008/05/29
投稿数: 25
投稿日時: 2008-09-10 16:46
>TabPageの再描画Visible()ではなくReflesh()が正しいような気がしますがいかがでしょうか?
「再描画」とは違うので、Refleshメソッドを使うこととは違います。
後からわかってきたのですが、タブ及びタブ内の各コントロールが作成される前または途中にバインドされてしまうことが原因のようです。

例えばこちらで発生した現象ですと、データが数十件あり明らかにそのDataGridView内に収まり切らないのにスクロールバーが使用不可のままになっているなど、バインドのタイミングが正しくない為にコントロールが中途半端なまま生成されてしまいます。
Loadイベントで意図的にVisibleプロパティをTrueにしているのは、まず最初にコントロールの作成を完了させるためです。

DataGridViewの再作成で解決できたのは、上記で示したのと同じく
一度コントロールを完成させ、その上でバインド設定を行うようにした為ではないでしょうか。

Refleshメソッドは、飽くまで「そのコントロール自体を再描画」ですから、
コントロールが中途半端に作成されたままなら、再び描画しても中途半端なままになってしまいます。
1

スキルアップ/キャリアアップ(JOB@IT)