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

DataGrid 再スクロール

環境/言語:[環境(WindowsXP)、使用言語(C#)]
分類:[.NET]

DataTableと連結されているDataGridで下記のことをやろうとしていますが、
うまくいきません。どなたか教えてください。

DataGridの表示できる行数が、20行で更新する行が100行目である場合、
一度DataGridを100行目まで、スクロールをしてからDataGrid_MouseDownイベント
などを使用し、データコマンドによってData更新をしているのですが、
更新後、DataGridにDataを表示し直すと、最初の20行の状態でしか表示できま
せん。
「DataGrid内の指定された行までスクロールする」
http://dobon.net/vb/dotnet/programing/invokenonpublicmember.html
を参考にしてみましたが、100行目をDataGridの1行目に表示させるのではなく、
あくまで上記のように100行目までスクロールした画面の状態で
DataGridを再表示したいと思っています。

宜しくお願いいたします。
2006/01/07(Sat) 17:24:10 編集(投稿者)

■No14386に返信(C#Beginnerさんの記事)

こんにちは エツです。

データコマンドによってData更新とはコードによるデータ更新ですか?

そうならば
DataGrid_MouseDownイベントでセルの更新はできているとして単に表示の問題であれば一旦DataGrid外のコントロールにフォーカス設定し、再びDataGridにフォーカスを戻せばいいと思います。

例えばフォームにlabel1コントロールがあるとすれば
セルの更新処理の最後に次の2行を追加します。
label1.Focus();
DataGrid1.Focus();

> 「DataGrid内の指定された行までスクロールする」
> http://dobon.net/vb/dotnet/programing/invokenonpublicmember.html

再スクロールする必要はありません。従って「DataGrid内の指定された行までスクロールする」を使う必要はありません。
エツ さん返信ありがとうございます。

返信が遅くなり申し訳ございません。

DataGrid_MouseDownイベントを使っての更新ですが、
上記イベントを使ってDataGrid上の更新したいセルを選択し、その後は
DataGrid上で更新処理を行わず、選択したセルの種類によって指定したFormを展開
しその後、展開されたFormでOleDbCommandをExecuteNonQuery()することにより、DataGridに連結しているDataTableの元のDataを更新した後、・・DataAdapter.Fill(DataTable名);によって、DataGridを再表示しています。

返信いただいた内容で再度挑戦いたしましたが、結果は変わらずDataTableの最初の
行でDataGridが表示されてしまいます。
label1.Focus();
DataGrid1.Focus();
でこの条件ではできないと思われますが、もしやり方があれば、再度教えてください。
■No14395に返信(C#Beginnerさんの記事)

こんにちは エツです。

> 展開されたFormでOleDbCommandをExecuteNonQuery()することにより、DataGridに連結しているDataTableの元のDataを更新した後、

この時点でDataGridに再表示されると思います。

>・・DataAdapter.Fill(DataTable名);によって、DataGridを再表示しています。

DataAdapter.Fill(DataTable名); が不要なのでは?

試してみてください。
エツ さん返信ありがとうございます。

> DataAdapter.Fill(DataTable名); が不要なのでは?

を試してみましたが、結果は更新前の状態のままです。DataTableはAccessの
テーブルから作成しているのですが、OleDbCommandをExecuteNonQuery()する
ことにより、Accessのテーブルを更新してるのですが、DataTableはDataAdapter.Fill(DataTable名); によりAccessのテーブルから作成・更新
しているため必要かと思われます。
2006/01/08(Sun) 11:26:53 編集(投稿者)

■No14402に返信(C#Beginnerさんの記事)

おはようございます。

>DataTableはAccessの
> テーブルから作成しているのですが、OleDbCommandをExecuteNonQuery()する
> ことにより、Accessのテーブルを更新してるのですが、DataTableはDataAdapter.Fill(DataTable名); によりAccessのテーブルから作成・更新
> しているため必要かと思われます。

そうですね。DataTableのフィールド更新後にAccessのテーブルを更新していれば、DataAdapter.Fill(DataTable名); は不要かと思ったんですが、Formを切り替えたり、複雑なことをしていて、DataAdapter.Fill(DataTable名);が必要なのですね。

そうすると当初の質問に戻り大変です。
そこで代案ですが 100行にスクロールするなら、100行1列を現在のセルにしフォーカスを当てて選択セルが1目でわかるようにしたらどうでしょうか?

DataAdapter.Fill(DataTable名);
DataGrid1.CurrentCell = new DataGridCell(99, 0); //セルを設定
label1.Focus(); //フォーカス移動しても影響のないコントロール
DataGrid1.Focus(); //フォーカスを戻す

これなら簡単ですが。
#これが嫌だから苦労してるんだ! と怒られそうな気もしますが、御勘弁をお願いします。
エツさん代案ありがとうございます。

せっかくの代案ですが、

> DataGrid1.CurrentCell = new DataGridCell(99, 0); //セルを設定
> label1.Focus(); //フォーカス移動しても影響のないコントロール
> DataGrid1.Focus(); //フォーカスを戻す
>
でやってもスクロール位置がずれてしまい、ユーザーが更新した後では、
見づらい結果になってしまいました。
2006/01/08(Sun) 16:14:38 編集(投稿者)

■No14405に返信(C#Beginnerさんの記事)

こんにちは 以下の手順でできます。

1.DataGridの左上セルの座標を予め記憶する。(Plu)
2.マウスダウンした時左上セルの行、列を左上セルの座標(Plu)を使って収得し記憶する(Lr,Lc)
3.マウスダウンしたセル(修正セル)のセルの行、列(Chgr,Chgc)を記憶する
4.アプリケーションで色々な処理をする
5.DataAdapter.Fill(DataTable名);をして最初から表示する。

行を合わす手順
6. 2.で収得した(Lr,Lc)を現在のセルに指定する。これで目的の行のやや前方が表示される。
7. 左上セルの行、列を左上セルの座標(Plu)を使って収得し記憶する(Tlr,Tlc)
8. Lr==Tlr でOK。 Tlr<Lr なら前方が余分に表示されているので調整する。
9. Tlr<Lr なら(Lr+ct,Lc)を現在のセルに指定する。ctは1ずつ増やす。
10. Lr==Tlr になるまで7〜9 を繰り返す。

11.最後に3.で取得した(Chgr,Chgc)を現在のセルに指定する。

列も合わす場合は同様になります。
欠点は1.の座標の収得です。実験で求めました。

一応御参考までに
エツさん何度もありがとうございます。

マウスダウンした時左上セルの行、列を左上セルの座標(Plu)を使って収得し記憶する(Lr,Lc)

の仕方がいったいどの様にやればいいのかわかりません。

もしよろしければ、もう少し詳しく教えていただければ幸いです。
■No14409に返信(C#Beginnerさんの記事)

こんにちは

> マウスダウンした時左上セルの行、列を左上セルの座標(Plu)を使って収得し記憶する(Lr,Lc)
>

DataGridの指定された座標位置の情報を取得する
http://dobon.net/vb/dotnet/datagrid/hittest.html
を参照してください。
なお私の場合左上セルの座標は(40,40)でOKでしたので hti = grid.HitTest(e.X, e.Y);は hti = grid.HitTest(40, 40); となります。
(e.X, e.Y) はクリックしたマウスの座標ですから注意してください。


前回の回答のなかで
行を合わす手順の以下の部分は

>6. 2.で収得した(Lr,Lc)を現在のセルに指定する。これで目的の行のやや前方が表示される。
>7. 左上セルの行、列を左上セルの座標(Plu)を使って収得し記憶する(Tlr,Tlc)
>8. Lr==Tlr でOK。 Tlr<Lr なら前方が余分に表示されているので調整する。
>9. Tlr<Lr なら(Lr+ct,Lc)を現在のセルに指定する。ctは1ずつ増やす。
>10. Lr==Tlr になるまで7〜9 を繰り返す。

「DataGrid内の指定された行までスクロールする」
http://dobon.net/vb/dotnet/programing/invokenonpublicmember.html
を使用し収得している左上セルの行Lrを使用すれば簡単かもしれません。
エツさん ありがとうございます。

> なお私の場合左上セルの座標は(40,40)でOKでしたので hti = grid.HitTest(e.X, e.Y);は hti = grid.HitTest(40, 40); となります。

とのことですが、「左上のセル」を確認したいのですが、
30行まで表示できるDataGridがあるとしたとき、更新したい行(40行目)を
DataGridの表示されている上から6行目になるまでスクロールしたとします。
その場合DataGrid上で表示されている1行目は35行目になるのですが、
ここでいう「左上のセル」とは35行目のことでしょうか?
スクロールをした時のDataGrid上1行目がDataTableの何行目に該当するかが
分かれば、その後

「DataGrid内の指定された行までスクロールする」
http://dobon.net/vb/dotnet/programing/invokenonpublicmember.html

で解決できると思われるのですが、「左上セルの座標」でつまずいています。

よろしければ再度教えてはもらえないでしょうか?
■No14413に返信(C#Beginnerさんの記事)
こんにちは

> エツさん ありがとうございます。
>
>>なお私の場合左上セルの座標は(40,40)でOKでしたので hti = grid.HitTest(e.X, e.Y);は hti = grid.HitTest(40, 40); となります。
>
> とのことですが、「左上のセル」を確認したいのですが、
> 30行まで表示できるDataGridがあるとしたとき、更新したい行(40行目)を
> DataGridの表示されている上から6行目になるまでスクロールしたとします。
> その場合DataGrid上で表示されている1行目は35行目になるのですが、
> ここでいう「左上のセル」とは35行目のことでしょうか?
> スクロールをした時のDataGrid上1行目がDataTableの何行目に該当するかが
> 分かれば、その後
>
> 「DataGrid内の指定された行までスクロールする」
> http://dobon.net/vb/dotnet/programing/invokenonpublicmember.html
>
> で解決できると思われるのですが、「左上セルの座標」でつまずいています。
>
> よろしければ再度教えてはもらえないでしょうか?
>

そうです。 hti = grid.HitTest(40, 40); のセル行を収得すると35行目ですから34という値がえられます。座標(40,40)でセル行−1の場合は座標(45,45)とかに変えてください。座標(55,45)とか大きくなると次の行36行目になり35という値が得られます。あなたの場合の正確な座標が知りたければ
DataGridの指定された座標位置の情報を取得する
http://dobon.net/vb/dotnet/datagrid/hittest.html
のhti = grid.HitTest(e.X, e.Y);の次の行でブレークポイントをかけ、35行目のセルの端の部分をマウスでクリックし、e.X, e.Y の値を調べればわかります。
あとは

> 「DataGrid内の指定された行までスクロールする」
> http://dobon.net/vb/dotnet/programing/invokenonpublicmember.html
>

で解決します。
エツさん ありがとうございます。

教えていただいた様に、座標を取り左上のセルを取得することができました。

本当にありがとうございました。
解決済み!

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