• 締切済み

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) { }

みんなの回答

  • dell_OK
  • ベストアンサー率13% (740/5645)
回答No.2

・Form1で関数を作りその関数をForm2で使いたいのです なるほど。それでしたらこんな感じでどうでしょうか。 Form1 public void Save(DataGridViewRowCollection rows) { foreach (DataGridViewRow r2 in rows) { var index = int.Parse(r2.Cells["Index"].Value.ToString()); var r1 = dataGridView1.Rows[index]; r1.Cells[1].Value = r2.Cells[1].Value; r1.Cells[2].Value = r2.Cells[2].Value; r1.Cells[3].Value = r2.Cells[3].Value; } } Form2 private void savebtn_Click(object sender, EventArgs e) { Form1 f1 = (Form1)Owner; f1.Save(dataGridView1.Rows); } ・System.ArgumentException: 'Index という列は見つかりません。 createData()の中でIndexカラムを追加すれば大丈夫かと思っていたのですが、 以下の行は追加していただけましたか。 dt.Columns.Add("Index");//最後にForm1のRow.Indexを保持するカラムを追加 それはそうと。 環境がわからずに試しているのですが、 .NET Frameworkか.NETか、そのバージョンはなんでしょうか。 実は私の環境では、DataGridViewにSelectedRowsDoubleClickイベントがなくて、 別の方法でForm2を開いているのですが、 SelectedRowsDoubleClickイベントは自作でしょうか。

MMM5800
質問者

補足

ありがとうございます!!試してみます!! 環境記載漏れすみません(><) .NET Frameworkです! SelectedRowsDoubleClickは自作かもしれないです。ここは上司が教えてくれた通りに書きました。

  • dell_OK
  • ベストアンサー率13% (740/5645)
回答No.1

「関数を使いたい」と言うのがどのようなことかわからなかったので、ひとまずまるまるコーディングする方法です。 Form1 Form2を開くところは f2.ShowDialog(this); にして、 Form1を操作(変更)できないようダイアログでForm2を開き、 親フォームとしてthis(Form1のこと)を渡すようにしてください。 それと、Form2から直接Form1へ反映させるため、 Form1のdataGridView1 の Modifiersプロパティを True にしておいてください。 Form2 ※createData()とdataGridViewDisp2()はどうなっているのかわからないので適当に書いてます。 ---- 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, r.Index);//Row.Indexを追加 } dataGridViewDisp2(dt); } private DataTable createData() { var dt = new DataTable(); dt.Columns.Add(); dt.Columns.Add(); dt.Columns.Add(); dt.Columns.Add(); dt.Columns.Add("Index");//最後にForm1のRow.Indexを保持するカラムを追加 return dt; } private void dataGridViewDisp2(DataTable dt) { dataGridView1.DataSource = dt; dataGridView1.Columns["Index"].Visible = false;//Indexカラムを非表示 } private void savebtn_Click(object sender, EventArgs e) { Form1 f1 = (Form1)Owner; foreach (DataGridViewRow r2 in dataGridView1.Rows) { var index = int.Parse(r2.Cells["Index"].Value.ToString()); var r1 = f1.dataGridView1.Rows[index]; r1.Cells[1].Value = r2.Cells[1].Value; r1.Cells[2].Value = r2.Cells[2].Value; r1.Cells[3].Value = r2.Cells[3].Value; } } ----

MMM5800
質問者

補足

ありがとうございます。Form1で関数を作りその関数をForm2で使いたいのです><わかりにくくすみませんm(__)m >Form1のdataGridView1 の Modifiersプロパティを True にしておいてください。 Modifiersプロパティに Trueは選択も入力もできず、、、今はpublicになってます。 その状態で実行すると 【var index = int.Parse(r2.Cells["Index"].Value.ToString());】の部分で、System.ArgumentException: 'Index という列は見つかりません。 パラメーター名:columnName' というエラーが起きてしまします><

関連するQ&A

  • 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(); } } }

  • Form1からForm2へ値渡しの際

    DataGridViewでForm1で選択した行の1列目と3列目だけを、Form2のDataGridViewに表示するコードを書いています。 DataGridViewでForm1からForm2へ値渡しの際、複数行選択→ダブルクリックするとForm2が1行ずつ、行の選択数分出てしまいます。 Form2のDataGridViewに選択数分の行(例えば3行選択ならForm2のDataGridViewの画面に3行)出るようにしたいです。 ご教授お願い致します。 【Form1】 private void DataGridView1_SelectedRowsDoubleClick(Object sender, MouseEventArgs e) { //選択した行の取得 foreach (DataGridViewRow r in dataGridView1.SelectedRows) { //詳細画面を開く Form2 f2 = new Form2(); //選択行をForm2に渡す f2.setRowData(r); //Form2を開く f2.Show(); } } 【Form2】 public void setRowData(DataGridViewRow r) { //1列目と3列目を取り出す string s1 = r.Cells[1].Value.ToString(); string s2 = r.Cells[3].Value.ToString(); // データを作成する DataTable dt = createData(); //データテーブル(DGVの中身)にいれる dt.Rows.Add("2023年",s1,s2); //一覧を表示する dataGridViewDisp2(dt); }

  • C# 親フォームで指定した値を子フォームで表示する

    表題の件がうまくできず、困っています。 やりたいことは 親フォームのリストボックスで選択した インデックス番号をshouDialog()で立ち上げた子フォーム側の textBoxに表示したいんですが、 何も表示されず困っています。 namespace test { public partial class Form1 : Form { //リスト変数 public string listChoise; [STAThreadAttribute] static void Main() { Application.Run(new Form1()); } public Form1() { InitializeComponent(); } private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { listChoise = listBox1.SelectedIndex.ToString(); MessageBox.Show(listChoise);//←ここでは値がでます }     private void button1_Click(object sender, EventArgs e) { //子フォームを立ち上げる Form2 form = new Form2(); form.ShowDialog(); } } } ↓Form2クラス namespace test { public partial class Form2 : Form { public Form2() { InitializeComponent(); //リスト選択変数 Form1 list = new Form1(); textBox2.Text = list.listChoise; } } } この二つのクラスです。 とくにエラーはありません。 ちなみに >>>//リスト変数 >>>public string listChoise; の部分を public string listChose = "aaaaa"; としておくと、 子フォームのテキストボックスに"aaaaa"と表示されているようなんですが、 >>>listChoise = listBox1.SelectedIndex.ToString(); の値がちゃんと子フォームの方で受け取れていないようです。 結果はなにもひょうじされません。 子フォームの方で、 MessageBox.Show("listChoise");をしても 何も表示されません。 どんな原因が考えられますでしょうか。 よろしくお願いします。 環境:visualC# 2008 Express Edition

  • DataGridViewの値を別フォームに

    こんにちは。 1つ教えて頂けないでしょうか。 Form1にDataGridViewがあり、どれか1行ダブルクリックすると Form2にForm1のDataGridViewの7列目の値の条件で抽出した結果を Form2のDataGridViewに表示したいのです。 Form1からの受け渡しデータはForm2のテキストボックス(条件)に表示させ 受け渡されて来たときは表示ボタンをクリックしなくてもForm2の DataGridViewは表示したいのです。 それぞれのFormは作成し、Form1は Private Sub dgv_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgv.CellDoubleClick Dim f As New Form2 f.txt条件 = Me.DataGridView.SelectedRows(0).Cells(7).Value f.ShowDialog() End Sub とコーディングしました。 Form2は表示されるのですが、データの受け渡しができていないし f.txt条件 = Me.DataGridView.SelectedRows(0).Cells(7).Valueの部分でキャストできませんのエラーに なります。 DataGridViewの選択した値を別のフォームに渡し、そのまま別フォームのDataGridViewを表示させたいのですが。 わかる方おられましたら、教えて頂けないでしょうか。 大変申し訳ありませんが、どうぞよろしくお願いします。

  • 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 本当に困っています. よろしくお願いいたします.

  • 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 の一番下の行だけにデータが表示されてしまいます。(以前のボタン押下時に記入されたデータが消えてしまい、データの変更が確定されていないように見えます。) なぜなんでしょう?

  • VC++2008 フォーム間の変数の受け渡しについて

    フォーム1で DateTime d1; int year; d1 = DateTime::Now; year = System::Int32::Parse( d1.ToString("yyyy") ); で読み込んだ現在の年数を、フォーム2で使いたい場合どうすればいいのでしょうか? private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { Form2^ f = gcnew Form2(); f->Show(); } でForm2を読み込んでいるので、ここに「変数yearを使う」旨を書けばいいのかとも思いましたが、うまく行きませんでした。 使用しているのはVisualC++2008 ExpressEdition。 ボタンをクリックすると別フォームを表示して、そこで元のフォームで使った変数を使おうと考えています。

  • C#について・・・

    次のようなブログラムなのですが、ラジオボタンが上手く切り替わりません。 どこを修正すると上手くいくでしょうか? <<文字数オーバーのため省略>> public Form1() { // // Windows フォーム デザイナ サポートに必要です。 // InitializeComponent(); if(isJapanStyle) { label5.Text=string.Format("0時0分0秒"); label6.Text=string.Format("0時0分0秒"); } else { label5.Text=string.Format("00:00:00"); label6.Text=string.Format("00:00:00"); } // // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。 // <<文字数オーバーのため 省略>> static void Main() { Application.Run(new Form1()); } protected void button1_Click(object sender, System.EventArgs e) { if(isJapanStyle) { label5.Text=string.Format("{0}時{1}分{2}秒",dt.Hour,dt.Minute,dt.Second); } else { label5.Text=DateTime.Now.ToString("T"); } recTime=dt; timer2.Stop(); timer3.Start(); } private void button2_Click(object sender, System.EventArgs e) { Application.Exit(); } private void timer1_Tick(object sender, System.EventArgs e) { dt=DateTime.Now; if(isJapanStyle) { label4.Text=string.Format("{0}時{1}分{2}秒",dt.Hour,dt.Minute,dt.Second); } else { label4.Text=DateTime.Now.ToString("T"); } } private void timer3_Tick(object sender, System.EventArgs e) { keika=dt-recTime; if(isJapanStyle) { label6.Text=string.Format("{0}時間{1}分{2}秒",keika.Hours,keika.Minutes,keika.Seconds); } else { label6.Text=string.Format("{0}:{1}:{2}",keika.Hours,keika.Minutes,keika.Seconds); } } private void timer2_Tick(object sender, System.EventArgs e) { timer3.Stop(); } private void radioButton2_CheckedChanged(object sender, System.EventArgs e) { isJapanStyle=false; } private void radioButton1_CheckedChanged(object sender, System.EventArgs e) { isJapanStyle=true; } } }

  • 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) 長くなりましたが、よろしくお願いします。

  • C#でテキストボックスをクリック→フォームが開く→フォームで設定した値

    C#でテキストボックスをクリック→フォームが開く→フォームで設定した値を元のテキストボックスに入力 こんな感じのことをC#でやりたいのですがよくわからないので教えてください。 1. 親をForm1、子をForm2とします 2. Form1のTextBox1をクリックするとForm2が開いきます 3. Form2で設定した値をForm2の「入力」ボタンを押すとForm2が閉じてTextBox1に値が入力されます というものです。 ここで、textBoxは「クリックしたコントロール名を取得してForm2に渡したい」のです。 テキストボックスがたくさんあるので、textBox1とか決まった名前ではありません。 この部分がわからないのです。 ------------------------------------------------------- Form1: private void textBox1_Click(object sender, EventArgs e) {  Form2 fromItem = new Form2(sender);  DialogResult deRet = fromItem.ShowDialog(); } Form2: public Form2(object sender) {  InitializeComponent();  object pSender = sender; } private void button_input_Click(object sender, EventArgs e) {  ((System.Windows.Forms.TextBox)pSender).text = "hoge"; } ------------------------------------------------------- この程度しかわかりません。 正しい方法を教えてください。よろしくお願いいたします。

専門家に質問してみよう