• 締切済み

toolStripStatusLabelの書き換えでpanelのスクロール位置が変化

こんにちは。 Windows Vista Home Premium VC# 2008 Express Edition を使用しています。 dataGridView.SelectionChangedイベントによるtoolStripStatusLabel.Textの書き換え時に予期しない動作をするため困っています。 【詳細】 まずフォームのコントロールをドキュメントアウトライン風に表すと Form ┣ panel ┃ ┗ dataGridView ┗ statusStrip   ┗ tolStripStatusLabel このような状態にします。 そして、panelのAutoScrollプロパティをtrueに、dataGridViewのサイズをpanelよりも大きくします。 最後に、dataGridViewのSelectionChangedイベントにtoolStripStatusLabelのTextプロパティを書き換えるメソッドを追加します。 この状態で、垂直方向のスクロール位置が0より大きい時にdataGridViewのセルを選択すると、そのたびにpanelのスクロール位置が垂直・水平共にdataGridViewの0,0の位置になってしまいます。 これの原因と対処法をご存知の方がいらっしゃいましたら教えてください。 【色々試した結果】 ・panelをsplitContainer内に入れると上記したような動作は起きない。 ・他のpanel内に入れるだけではsplitContainerのように回避できない。 ・toolStripStatusLabel.Textを操作しなければ起きない。 ・文字列が変化しなければ同じ文字が代入されても起きない。 画像のフォームは、 左のpanel1とdataGridView1 : フォームに直接追加 右のpanel2とdataGridView2 : splitContainer内に追加 となっており、それぞれにSelectionChangedイベントが追加されています。起動後に適当にスクロールして適当にセルを選択した結果が画像となっています。 メソッドの内容は左側が int cc1 = 0; private void EVENT1(object s, EventArgs e) { // dataGridViewのセルに左上から // パネルのスクロール位置 + ", " を入力。 dataGridView1.Rows[cc1 / CC].Cells[cc1 % CC].Value = panel1.VerticalScroll.Value.ToString() + ", "; // 書き換え toolStripStatusLabel1.Text = panel1.VerticalScroll.Value.ToString(); // 最初に代入したdataGridViewのセルに // パネルのスクロール位置を追加 dataGridView1.Rows[cc1 / CC].Cells[cc1++ % CC].Value += panel1.VerticalScroll.Value.ToString(); } 右側のdataGridView.SelectionChangedに追加したメソッドは cc1, dataGridView1, panel1 の添字がすべて2になったものです。 CCはdataGridView.Columns.Countです。(図では CC = 4) 長くなりましたが、よろしくお願いします。

みんなの回答

  • oboroxx
  • ベストアンサー率40% (317/792)
回答No.1

ちょっと質問というか、提案というか、あれなんですが、DataGridViewをコンテナであるPanelにドッキングさせるのはダメなのでしょうか? それが出来るのであれば、DataGridViewのスクロールバーを使えば良いかなとも思うのですが。

aniline
質問者

お礼

こんばんは。 回答ありがとうございます。 使用するDataGridViewを印刷する場面があるので、パネル内に置いておけばキャプチャ時に楽ができるという意図(というか怠惰というか)がありまして……。 できればこのままパネルを用いて行えれば、と思います。。

aniline
質問者

補足

補足欄をお借りします。 回答がつかないようなので締め切らせていただきます。 ToolStripStatusLabelのテキスト変更の機能は削ろうと思います。。 2010/01/22

関連するQ&A

  • DGV/子フォームで編集して親フォームへ

    親フォームと子フォーム、どちらにもDataGridViewを用意し、親フォームのセレクト行を子フォームに表示するというプログラムがあります。 さらに子フォームで直接DataGridViewに入力し編集して、更新ボタンを押して親フォームに反映させたいです。(関数を使いたい) ご教授お願いします(´;ω;`) Form1 private void DataGridView1_SelectedRowsDoubleClick(Object sender, MouseEventArgs e) { Form2 f2 = new Form2(); f2.setRowData(dataGridView1.SelectedRows); f2.Show(); } Form2 public void setRowData(DataGridViewSelectedRowCollection rows) { DataTable dt = createData(); foreach (DataGridViewRow r in rows) { string s1 = r.Cells[1].Value.ToString(); string s2 = r.Cells[2].Value.ToString(); string s3 = r.Cells[3].Value.ToString(); dt.Rows.Add("12345", s1, s2, s3); } dataGridViewDisp2(dt); } private void savebtn_Click(object sender, EventArgs e) { }

  • C# datagridview データバインド系

    datagridviewのデータバインドについて教えてください. 今,下記のプログラム(一部)を組んで処理を行おうとしていますがうまくいかないため 何が悪いのか教えて頂けないでしょうか? 今datagridviewをデータテーブルにバインドしています. for (j = t; j < R - 1; j++) { object Ti = this.dataGridView1.Rows[j].Cells[0].Value; object Tibf = this.dataGridView1.Rows[j + 1].Cells[0].Value; string TiS = Convert.ToString(Ti); string TiSbf = Convert.ToString(Tibf); # region // シリアル値化 long serial = DateTime.Parse(TiS).ToBinary(); long serialbf = DateTime.Parse(TiSbf).ToBinary(); long parsesum = serial + Oneparse; if (serialbf != parsesum) { dataGridView1.Rows.Insert(j + 1, 1); // シリアル値から復元 DateTime dtm = DateTime.FromBinary(parsesum); string s = Convert.ToString(dtm); // 指定した書式で日付を文字列に変換する string stPrompt1 = dtm.ToString("yyyy/M/d H:mm"); this.dataGridView1.Rows[j + 1].Cells[0].Value = stPrompt1; } } 簡単に言うと,行を追加したいのですが,forの前でデータソースをnullにすると object Ti = this.dataGridView1.Rows[j].Cells[0].Value;でエラー if (serialbf != parsesum)の後にすると dataGridView1.Rows.Insert(j + 1, 1);でエラー が起こります.どちらの場合も下記のエラーが出ます. インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。 パラメーター名: index 本当に困っています. よろしくお願いいたします.

  • DataGridViewについて

    Fom1のDataGridViewから選択した行のデータをForm2のDataGridViewに渡し、Form2で編集しFom1に反映せると、どの行のデータも1行目に入ってしまいます。 どのようなコードで解決できますか? 【Form1】 private void DataGridView1_SelectedRowsDoubleClick(Object sender, MouseEventArgs e) { // Form2を作成し、親フォームとしてForm1を設定する Form2 f2 = new Form2(); f2.Owner = this; // 親フォームを設定 // 選択行のデータを渡す f2.SetRowData(dataGridView1.SelectedRows, dataGridView1); // Form2を表示する f2.Show(); } /// <summary> /// 選択行のデータを更新するメソッド public void UpdateSelectedRowData(int rowIndex, string editedData1, string editedData2, string editedData3) { // データソースが DataTable の場合のみ処理を実行する if (dataGridView1.DataSource is DataTable dt && dt.Rows.Count > rowIndex) { // データ行を取得する DataRow dataRow = dt.Rows[rowIndex]; // 編集データを新しいデータ行にセットする dataRow["date"] = editedData1; dataRow["name"] = editedData2; dataRow["week"] = editedData3; } } } } 【Form2】 public void SetRowData(DataGridViewSelectedRowCollection rows, DataGridView dataGridView)  { //データテーブルの作成 DataTable dt = createData(); foreach (DataGridViewRow r in rows) { //1列目~3列目を取り出す string s1 = r.Cells[1].Value.ToString(); // 日付 string s2 = r.Cells[2].Value.ToString(); // 名前 string s3 = r.Cells[3].Value.ToString(); // 曜日 dt.Rows.Add("2023年", s1, s2, s3); //日付順に昇順に表示する dt.DefaultView.Sort = "日付 ASC"; } //一覧を表示する dataGridViewDisp2(dt); } // 編集後のデータを保持するためのプロパティ public string EditedData1 { get; set; } public string EditedData2 { get; set; } public string EditedData3 { get; set; } /// 更新ボタンの処理 private void savebtn_Click(object sender, EventArgs e) { // 親フォーム Form1 をForm1に指定する Form1 form1 = this.Owner as Form1; if (form1 != null) { // Form1のDataGridViewのデータソースを取得する DataTable dt = form1.dataGridView1.DataSource as DataTable; if (dt != null) { // dataGridView2の各行を処理する foreach (DataGridViewRow row in dataGridView2.Rows) { // 新規行はスキップする if (row.IsNewRow) continue; // 編集されたデータを取得する string editedData1 = row.Cells[1].Value.ToString(); string editedData2 = row.Cells[2].Value.ToString(); string editedData3 = row.Cells[3].Value.ToString(); // 選択された行のインデックスを取得する int rowIndex = row.Index; // 親フォーム Form1 の UpdateSelectedRowData メソッドを呼び出す form1.UpdateSelectedRowData(rowIndex, editedData1, editedData2, editedData3); } } } // 現在のフォームを閉じる this.Close(); } } }

  • C# .NET DataGridView の行を追加するとデータが消える。

    すぐ下に先ほど書いた質問がありますが、こちらに難点か追記してあります。下の質問は後ほど消します。(何でか、今現在消せないそうなので。) 環境 WindowsXP SP2 VisualStudio.NET 2005 C# テストプログラムで、こんなコードを書きました。 private void button1_Click(object sender, EventArgs e) { int iMaxCnt; dataGridView1.Rows.Add(1); iMaxCnt = dataGridView1.RowCount ; dataGridView1.EndEdit(); dataGridView1.Rows[iMaxCnt-1].Cells[0].Value = "たちつてと"; dataGridView1.Rows[iMaxCnt-1].Cells[1].Value = "なにぬめの"; dataGridView1.Rows[iMaxCnt-1].Cells[2].Value = "はひふへほ"; dataGridView1.EndEdit(); } ボタンのクリックイベントなので、これを何度か実行すると、DataGridView の一番下の行だけにデータが表示されてしまいます。(以前のボタン押下時に記入されたデータが消えてしまい、データの変更が確定されていないように見えます。) なぜなんでしょう?

  • DataGridViewのRowsにメソッド追加

    VB2013で、DataGridViewのRowsコレクションに独自のメソッドを追加することは可能でしょうか。 Inherits System.Windows.Forms.DataGridViewで継承してメソッドを追加するだけでは DataGridView.XXXといった形式になってしまうので・・・。 よろしくお願いいたします。

  • DataGridViewのデータをComboBoxの項目に追加する

    回答お願い致します。 現在、VB2005を勉強していてDataGridViewを学んでいます。 DataGridViewの項目に(教員番号,教員名)とあるとして、教員名のデータをComboBoxの項目に追加したいと考えています。 普通に項目を追加するのなら、 For intLoop = 0 To DataGridView.Rows.Count - 1 ComboBox.Items.Add(DataGridView.Rows(intLoop).Cells (1).Value) Next といった感じで出来るのですが、これだと教員名が重複している場合も全てComboBoxに項目を追加してしまうので、それを避けて項目を追加する良い方法はないでしょうか?

  • C#でパネルに子パネルを上から降順追加したいです。

    図のように"追加ボタン"を押すと親パネル(panel1)に子パネル(panel2)を上から 追加する画面を作りました。(以下がソースです) private void button1_Click(object sender, EventArgs e) { int i = 0; foreach (Panel p in panel1.Controls) { i++; p.Top += 40; } Panel panel2 = new Panel(); createPanel(panel2, i);※子パネルのレイアウトを設定し、確認用の連番をセットしています panel1.Controls.Add(panel2); } 常に親パネルの最上段に子パネルを追加したいのですが、 スクロールバーで親パネルの下のほうで追加ボタンを押すと、 親パネルの表示されている最上段の位置に子パネルが追加されてしまいます。 スクロールバーで親パネルの最下部に移動していても、追加するときは親パネルの(0,0,)の位置に 子パネルを表示させるにはどのように実装したらよいでしょうか? メソッドcreatePanel(panel2, i)の中で、 子パネルのロケーションを0,0に設定してもダメでした。 以上、よろしくお願いいたします。

  • datagridviewに行追加し、値を入れたいです。VB.NET 

    'データグリッドの選択された値を変数frowに代入する。 frow = DataGridView1.SelectedCells.Item(0).Value 'データグリッドの選択された値を変数srowに代入する。 srow = DataGridView1.SelectedCells.Item(1).Value 'データグリッドに新しい行を追加する。 KYU70000_1.DataGridView1.Rows.Add(DataGridView1.Rows) KYU70000_1.DataGridView1.Rows.Add(DataGridView1.Rows) '選択された値をKYU70000_1のデータグリッドに代入する。 frow = KYU70000_1.DataGridView1.SelectedCells.Item(0).Value ←ここがインデックスが範囲を超えています、となります。 srow = KYU70000_1.DataGridView1.SelectedCells.Item(1).Value どうすれば良いのでしょうか?教えてください。意味が分かりません。

  • DataGridViewで再表示すると変更不可にならない

    Visual Basic 2008 にて開発していますがDataGridViewについて質問させて下さい。 DataGridViewのデータ表示は、検索結果をDataTableに格納し、 そのDataTableをDataSourceに設定する方法で行っています。 DataGridView内にはチェックボックスがあり、 そのチェックボックスは条件によってReadOnly = Trueにて変更不可にして表示しています。 最初の表示は問題なく条件に合えば ReadOnly = Trueにて変更不可になり表示してくれますが、 再表示(DataTableをDataSourceに再代入)すると条件に合っているのにReadOnly = Trueが効かず、 チェックボックスが変更可能となって表示してしまいます。 ReadOnly=True にする方法は、DataGridView の件数を取得し、 jjCnt = 0 Do Until jjCnt >= ggCnt   If DataGridView1.Rows(jjCnt).Cells(88).Value.ToString() = "1" Then DataGridView1.Rows(jjCnt).Cells(0).ReadOnly = True End If jjCnt = jjCnt + 1 Loop で行っています。 何故、再表示だと変更不可にならないのか解らずご教授願いたく宜しくお願い致します。

  • 位置の把握

    お世話になります。 下記の様な記述で、最下セルの位置を知る事が出来ますが、 同じ様に行方向ではどう言う様に記述内容を変えたらいいで しょうか。 お教え頂きたく宜しくお願いします。    記 r = Sheets("sheet1").Cells(Rows.Count, 1).End(xlUp).Row

専門家に質問してみよう