「忠犬もちしば」のAIボットを作ろう!

C#でシステム作成をしています。WindowsFormApplicationです。
どのようなシステムかと申しますと、学習システムです。

親フォームForm1には、問題ページForm2へ行くボタン、保存ボタン、開くボタンが配置されています。
問題ページForm2へ行くと、数十個の数字labelがあり、この各labelから実際の問題へ、つまり、Form3、Form4、…と行きます。
さらにForm3、Form4、…の各問題を終える度に、Form3、Form4…からその都度別Forms(集計のsとしておきます。)を開いて集計していきます。(数値を扱うので。)

Form1からForm2は同時表示、Form2のlabelからのForm3、4…はForm2をHideして表示(Hideについては後述)、Form3、4…からFormsは、もちろん3、4を参照しながら集計するので同時表示です。
Form2のHideについては、例えばForm3の問題を解き、Formsを開いて集計したなら、Form3をCloseすると、Form2を再度ShowしてForm3へのlabelのForeColorを変化させます。同時にFormsはHideします。(また次のForm4で使うため。)変色labelを再度押すと、「解答済みです」とMessageBoxに表示して行けなくなります。
このように進めていくタイプのシステムを作成しています。
以上まではうまくいきました。

ここからが問題です。
Form2のlabelの色は、Form2を閉じない限りはもちろん保持されます。しかし、閉じて再度Form1から表示すると色が保持されているプログラムを書きたいのですが、どのようにすればいいでしょうか?
ちなみにHideではだめだと思います。なぜなら、初めてこのシステムに取り掛かる際、Form1からForm2を表示する時に、HideされたForm2はまだ存在しないからです。
だからデータの受け渡し、つまり、Form2を閉じる時にForm1へデータを渡し、再度開く際にForm2へそのデータを返す、というイメージですかね。
インターネット上では、テキストボックスのテキストデータの例ばかりでしっくりきません。
渡すとしてもForm1のどこに渡すのか(どこにプログラムを?)も分かりません。
Form2から受け取る際は、Loadイベントでしょう。Form2から渡す際はClosedイベントで渡すとは思いますが…。

そしてあと一つ、Form1の保存ボタン、開くボタンのプログラムです。
学習システムで少しずつ進めていくプログラムですから、この日はここまで、と保存していく必要があります。
それを開く意味で、開くボタンも付けています。
このプログラムも難しくて分からないところですが、これも質問すると質問が多くなるため置いておきます。(というより先述の受け渡しのプログラムの質問が優先です。)
質問は、このシステムのForm1から保存することで、きちんと進度は保存されるかということです。
ある日、あるところまで問題を解き(labelの色を変え)、集計し終えたとします。
そして保存して、別の日に開くとForm1が現れます。
このForm1からForm2へ行くと、ちゃんと色が保持されたプログラムは書けるでしょうか?
(ちゃんとデータの受け渡しプログラムを書いたと想定。要はlabelの変色のみ保存できればいいのです。)
そしてFormsへ飛ぶと、データは保持されているでしょうか?
Formsは先述しましたが、集計し終えるとHideするのみです。つまりFormsは初めて表示したらもうCloseはしません。
このようにHideしたFormの状態も保持することはできるでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (3件)

同じような問題に同じ時期にハマる人がいるんですねぇ。


同じチームの人たちなのかも知れませんが。


とりあえず、データに関しては#2さんの書かれているようにクラスなりにまとめて、
フォーム間でのやりとりはプロパティ経由なり、受け渡し用のアクセスメソッド入れたり…でよいのではないですか?

最初に起動するであろうメインフォームのフィールドにデータを保持するクラス/構造体のインスタンスを持って、子フォームには親フォーム経由で受け渡し。
# カレンダーの例では面倒ですが個々のデータを送るしかないでしょう。

あるいは、親フォームの方にデータ受け渡し用のプロパティかアクセス用メソッドを用意して、子フォームからアクセスする。とかでしょうかね。
# カレンダーなら表示更新の際に表示に必要な情報を親フォームに問い合わせればいいし。それなら最大で31日分です。
    • good
    • 0

Formにデータを保持させるのではなくて、それらデータを統合的に扱うクラスなりを用意すればいいのでは。

    • good
    • 0

http://okwave.jp/qa/q8804320.html
これの関連じゃねーの?
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC#「オブジェクト参照が必要です」(初心者)

Visual C# 2008を学習中なんですが、とりあえず何か作ってみようと思って、パラパラマンガに挑戦してみました。
Form1にpictureBox1を作り、waitを入れてイメージを書き換えるという単純なものです。
ところが実行しようと思ったら、「静的でないフィールド、メソッド、またはプロパティ’WindowsFormApplication1.Form1.pictureBox1’でオブジェクト参照が必要です」というエラーが出ます。その際のフォーカスは、main()内の
Form1.pictureBox1.image = Image.FromFile("motion1.png");
”Form1.pictureBox1”に当てられています。

何が原因と考えられるでしょうか。
もし情報不足であればご指摘いただくか、あるいはこの目的においてやらなければいけないこと、を大雑把に教えていただくだけでも幸いです。
よろしくお願いします。

Aベストアンサー

main()内に記述されているとのことですので、たぶん、
Form1.pictureBox1.Image=Image.FromFile("motion1.png");
Application.Run(new Form1());
と書いているのではないでしょうか?

連載 改訂版 C#入門 第3章 クラスとインスタンス
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_003/cs2_003_01.html#cs0302

ここであるように、オブジェクト指向にはクラスとインスタンスという概念があります。
今のコードでは、Form1クラスを操作しようとしているのでそのようなエラーが出ます。

具体的な解決方法としては、PictureBoxに初期画像を設定する処理をForm1のコンストラクタでやるのがいいと思います。
その際、redfox63さんがおっしゃられるように
this.pictureBox1
と記述することが必要です。(thisは自分自身のインスタンスを指します)

後は、Windowsフォームで一定間隔での処理をするための「Timerコンポーネント」について調べてみたらいいと思います。

タイマにより一定時間間隔で処理を行うには?(Windowsタイマ編)
http://www.atmarkit.co.jp/fdotnet/dotnettips/372formstimer/formstimer.html

MSDNライブラリ Timerクラス
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.timer.aspx

参考URL:http://www.atmarkit.co.jp/fdotnet/csharp_abc2/index/

main()内に記述されているとのことですので、たぶん、
Form1.pictureBox1.Image=Image.FromFile("motion1.png");
Application.Run(new Form1());
と書いているのではないでしょうか?

連載 改訂版 C#入門 第3章 クラスとインスタンス
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_003/cs2_003_01.html#cs0302

ここであるように、オブジェクト指向にはクラスとインスタンスという概念があります。
今のコードでは、Form1クラスを操作しようとしているのでそのようなエラーが出ます。

具...続きを読む

QC# 別なフォームへ値を渡す (初心者です)

メインのフォームからサブのフォームを呼び出して、
サブのフォ-ムからさらにクラスを呼び出し、
クラスからメインのテキストボックスのテキストに書き込むプログラムを作成中です。

ですが、テキストボックスがパブリックにも関わらず、表示されません。
デバックで見る限り、テキストボックスのテキストには値が入っているのですが、
フォームを見ると表示されていません。

知恵をお貸しください。

Aベストアンサー

普通にメソッドに変数を渡すのと一緒の感じでいいですよ。
例えば、フォームのコンストラクタに渡す感じで。
A_Form : メインフォームの型
B_Form : サブフォームの型
C_Form : 子フォームの型
とします。
class B_Form : Form
{
 private A_Form main_form;
 public B_Form(A_Form a)
 {
  main_form = a;
 }
}

class C_Form : Form
{
 private A_Form main_form;
 public C_Form(A_Form a)
 {
  main_form = a;
 }
}

public void some_function()
{
 A_Form a = new A_Form();
 B_Form b = new B_Form(a);
 C_Form c = new C_Form(a);
}

といった感じになるかと。
最後のメソッドはたとえばなので、参考程度に。

http://www.stackasterisk.jp/tech/dotNet/csharp02_01.jsp

普通にメソッドに変数を渡すのと一緒の感じでいいですよ。
例えば、フォームのコンストラクタに渡す感じで。
A_Form : メインフォームの型
B_Form : サブフォームの型
C_Form : 子フォームの型
とします。
class B_Form : Form
{
 private A_Form main_form;
 public B_Form(A_Form a)
 {
  main_form = a;
 }
}

class C_Form : Form
{
 private A_Form main_form;
 public C_Form(A_Form a)
 {
  main_form = a;
 }
}

public void some_function()
{
 A_Form a = new A...続きを読む

QC# ログイン画面からメイン画面への画面遷移について

C# ログイン画面からメイン画面への画面遷移について

C#での画面遷移に関する質問です。
ログイン画面からメイン画面に遷移する場合、どの様な方法で遷移すれば良いのか
迷っています。

現状では以下の方法で遷移していますが、より適切な方法をご存じの場合
ご教示下さい。

(1)Program.csにおいてApplication.Run(new LoginDialog())で
ログイン画面を表示

(2)ログインボタンクリックメソッドでログイン成功時、
メイン画面インスタンスを生成・表示し、ログイン画面を非表示。
(後でログイン画面を再表示することがある為)

---------------------------------------------------------------------
private void LoginButton_Click(object sender, EventArgs e)
{
   /* ログイン処理 */

   //ログイン成功時
   //メイン画面インスタンス生成
   MainForm mainForm = new MainForm();
   //ログイン画面インスタンスを代入
   mainForm.loginForm = this;
   //メイン画面表示
   mainForm.Show();
   //ログイン画面非表示
   this.Visible = false;
}
---------------------------------------------------------------------

また上記の方法だとメイン画面を閉じても、アプリケーションは終了しない為
メイン画面の閉じるボタンを押した場合に以下の処理を行っています。

---------------------------------------------------------------------
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
   //ログイン画面クローズ
   loginForm.Close();
}
---------------------------------------------------------------------

以上、宜しくお願いします。

C# ログイン画面からメイン画面への画面遷移について

C#での画面遷移に関する質問です。
ログイン画面からメイン画面に遷移する場合、どの様な方法で遷移すれば良いのか
迷っています。

現状では以下の方法で遷移していますが、より適切な方法をご存じの場合
ご教示下さい。

(1)Program.csにおいてApplication.Run(new LoginDialog())で
ログイン画面を表示

(2)ログインボタンクリックメソッドでログイン成功時、
メイン画面インスタンスを生成・表示し、ログイン画面を非表示。
(後でログイン画面を再表示す...続きを読む

Aベストアンサー

#2です。
最初にログイン画面のみを表示したいなら
メイン画面のForm_menu_Load(loadイベント処理)
の中で、ログイン画面をモーダル表示し、
NGならメイン画面のcloseのほうがよいかも知れません。

QC#でのフォーム間のデータの受け渡しについて

フォーム間のデータ(パラメータ等)の受け渡しについて教えてください。
現在Form1からForm2を起動させる場合、以下のようにForm2のインスタンスの生成時のパラメータを設定してもForm2のLoadイベントでは拾うことはできないのでしょうか?
↓実際のコード
//Form1クラスのインスタンスを作成する
//引数(a,b)
Form2 f = new Form2(a,b);
//Form1を表示する
//ここではモーダルダイアログボックスとして表示する
//オーナーウィンドウにthisを指定する
f.ShowDialog(this);
//フォームが必要なくなったところで、Disposeを呼び出す
f.Dispose();

また、上記の方法が違っていた場合、方法としてどのようなやり方があるのか教えてください。
よろしくお願いいたします。

Aベストアンサー

質問の意味がわからないんですが・・・(^-^;

Form2 f = new Form2(~);
でインスタンス生成をしているのですから、この時のパラメータは
コンストラクタに渡っています。

インスタンス生成時に渡されているパラメータなのですから、
Loadイベント以前の問題です。

QC#にて別クラスの関数を使いたい

C#にて、別クラスの関数を使用する方法を教えてほしいです。

下記のような、構造体を受け取るメソッドを作りました。

*****************************
private struct MyPoint
{
public int x;
public int y;
}

private void proc1(MyPoint pt)
{
MessageBox.Show("座標:" ; pt.x + "," + pt.y + "実行結果");
}

private void button1_Click(object sender ,System.EventArgs e)
{

MyPoint pt;
pt.x = 10;
pt.y = 20;
proc(pt);
}
*****************************

別のフォームのクラスから、proc1を呼び出したいのですが、やり方がわかりません。
どうか、教えてください。

Aベストアンサー

同じ定義をしたとしても別の名前空間に書いた構造体は同一とはみなされません。

呼び出し先クラスでの構造体を private では無く、public で宣言して下さい。

呼び出し元では、

MyClass.MyPoint pt;

のようにして実体を作ります。

QDataGridViewで指定したセルの値を取得

こんにちは。

VB2008のDataGridViewで指定したセルの値を取得をする方法がわかりません。
どなたか教えてください。

Aベストアンサー

こんばんは.

 Dim Data As String
 Data = Me.DataGridView(0, 2).Value
 MsgBox(Data)

みたいな感じで取れないですかね???

Qフォーム間の値の渡し方

こんにちわ。

C#で以下のようなことを実現しようとしています。
フォームA
・コンボボックスを選択⇒SelectedIndex値を変数Pへ
・フォームBを開く

フォームB
・変数Pを読み込み処理

1.ここで、フォームAでSelectedIndexの値は変数Pに入っているのですが、
その値をフォームBで呼び出す方法がわかりません。
以下のコードでは、「System.Windows.Forms.FormにPの定義がありません」となってしまいます。
2.変数Pはpublicで宣言しているのですが、
それだけで全てのフォームから呼び出せる変数となるわけではないのでしょうか?

ちなみに以下のようなコードにしてあります。
*********フォームA*********
public int P;

private void btn1_click(object sender, System.EventArgs e)
{
P = comboBox.SelectedIndex;

F_B f1 = new F_B();
f1.ShowDialog();
}

*********フォームB*********
private void F_B_Load(object sender, System.EventArgs e)
{
switch (Owner.P)
{
case 0:
・・・・
case 1:
・・・・
}
}

どなたかアドバイスをお願いいたします。

こんにちわ。

C#で以下のようなことを実現しようとしています。
フォームA
・コンボボックスを選択⇒SelectedIndex値を変数Pへ
・フォームBを開く

フォームB
・変数Pを読み込み処理

1.ここで、フォームAでSelectedIndexの値は変数Pに入っているのですが、
その値をフォームBで呼び出す方法がわかりません。
以下のコードでは、「System.Windows.Forms.FormにPの定義がありません」となってしまいます。
2.変数Pはpublicで宣言しているのですが、
それだけで全てのフォームから呼び出せる変数...続きを読む

Aベストアンサー

整理しましょ。ここで話題なってるのは、次の2通りです。
1.親子関係を利用して他フォームの値を取得する。(Ownerプロパティ)
2.親フォームの参照を子フォームに渡すことにより、他フォームの値を取得する。(これは私が書いているものです。私が違う方式を書いて混乱されたかもしれません。ごめんなさい)
この他、インターフェースを利用しても実現できますが(一番汎用性が高いがコード量も一番多い)、おいおい勉強していきましょう。
とりあえず、以下のページがわかりやすいと思います。

キャストとは型を変換して、変換した型固有の操作を可能にするものです。う~ん、わかりやすく言うと、人間というオブジェクトがあった時(実は女性とします)、男性にキャストしようとすると失敗します。実は女性だからです。で、女性にキャストすると成功します。実は女性だからです。女性にキャストできたので、女性が持っている固有の特徴が利用できるようになります。女性.子供を生む みたいな。

続いてインスタンス。クラスを記述するとは設計図を描いているようなものです。例えば車のクラスを記述することは、車の設計図を書いているに他なりません。車の設計図を書いたからって、ドライブできませんよね。設計図から実際に車を作る必要があります。こうして実際に作った車がインスタンスです。
設計図(クラス)があれば車(インスタンス)はいくらでも作れます。
Car car1 = new Car();
Car car2 = new Car();
Car car3 = new Car();
. .
. .
. .
オブジェクト指向でプログラミングするとは、設計図(クラス)を用意しておき、必要な時に実体化(インスタンス)させて働かすようなイメージです。

参考URL:http://dobon.net/vb/dotnet/form/accessanotherformdata.html

整理しましょ。ここで話題なってるのは、次の2通りです。
1.親子関係を利用して他フォームの値を取得する。(Ownerプロパティ)
2.親フォームの参照を子フォームに渡すことにより、他フォームの値を取得する。(これは私が書いているものです。私が違う方式を書いて混乱されたかもしれません。ごめんなさい)
この他、インターフェースを利用しても実現できますが(一番汎用性が高いがコード量も一番多い)、おいおい勉強していきましょう。
とりあえず、以下のページがわかりやすいと思います。

キャ...続きを読む

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

表題の件がうまくできず、困っています。

やりたいことは
親フォームのリストボックスで選択した
インデックス番号を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

表題の件がうまくできず、困っています。

やりたいことは
親フォームのリストボックスで選択した
インデックス番号をshouDialog()で立ち上げた子フォーム側の
textBoxに表示したいんですが、
何も表示されず困っています。

namespace test
{
public partial class Form1 : Form
{
//リスト変数
public string listChoise;


[STAThreadAttribute]
static void Main()
{
Application.Run(new Form1());
}


...続きを読む

Aベストアンサー

子ダイアログから 親をアクセスしたいなら その親を取得する方法を指定しましょう

子ダイアログを表示(実行)する前に 親側から子側にデータを受け渡すなら
子側に フィールド準備しておいてそのフィールド設定してから ShowDialogを実行する
たとえな Form2側に
public string myEditData;
といったフィールドを準備して

Form2 form = new Form2();
frm.myEditData = listChoise;
form.ShowDialog();
などとして実行

Form2のLoadイベントで
textBox2.Text = myEditString;
といった具合に初期化する

--------------------------------
子側から親にアクセスするなら
frm.ShowDialog( this );
といった具合に親のオブジェクトを渡す

子側のLoadイベントで
textBox2.Text = ((Form1)this.Owner).listChoise;
といった具合に初期化してみましょう

子ダイアログから 親をアクセスしたいなら その親を取得する方法を指定しましょう

子ダイアログを表示(実行)する前に 親側から子側にデータを受け渡すなら
子側に フィールド準備しておいてそのフィールド設定してから ShowDialogを実行する
たとえな Form2側に
public string myEditData;
といったフィールドを準備して

Form2 form = new Form2();
frm.myEditData = listChoise;
form.ShowDialog();
などとして実行

Form2のLoadイベントで
textBox2.Text = myEditString;
といった具合に初期化...続きを読む

QVisual C♯ フォーム間での値の受け渡し

Visual C♯
フォーム間での値の受け渡しについて
プログラミング初心者です。
今、勉強中なのですが、試行錯誤しても出来なかったので助けていただければと思います。

現在Visual C# 2008を使っております。
フォーム間の値の受け渡しについて、助言をお願いします。

[Form1]
・TextBox1
・Button1

[Form2]
・TextBox2
・Button2

1.Form1のButton1をクリックし、Form2を出す。
2.Form2のtextBox2に文字を入力し、Button2をクリックする。
3.Form1のTextBox1に、Form2のtextBox2に入力した文字を表示する。

という、作業をしたいのです。
できればソース付きで教えていただけると助かります。
よろしくお願いします。

Aベストアンサー

簡単なやり方で...

1.Form1のTextBox1のModifiersをPublicに変更します。
2.下記のソースを各イベントに書き込む

[Form1のButton1クリックイベントソース]

private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(); // Form2を生成する

f2.Show(this); // Form2を表示するときに、表示元(Form1)を引数として渡す
// これをすることでForm2でForm1のTextBox1を参照出来るようになります。
}


[Form1のButton2クリックイベントソース]

private void button2_Click(object sender, EventArgs e)
{
Form1 f1 = (Form1)this.Owner; // Form2のOwnerをForm1でキャスト

f1.textBox1.Text = this.textBox2.Text; // Form1のTextBox1にForm2のTextBox2の内容をコピー
}

これで上記、要件は満たされると思います。
また、「フォーム間の値の受け渡し」をキーワードにすれば、参考に出来るURLは出てくると思いますので
がんばってください。

簡単なやり方で...

1.Form1のTextBox1のModifiersをPublicに変更します。
2.下記のソースを各イベントに書き込む

[Form1のButton1クリックイベントソース]

private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(); // Form2を生成する

f2.Show(this); // Form2を表示するときに、表示元(Form1)を引数として渡す
// これをすることでForm2でForm1のTextBox1を参照出来るようになります。
}


[Form1のButton2クリックイベントソ...続きを読む

QC#でTextBoxに数値のみ入力可能とする方法

C#の超初心者です。C#.NETでWindows環境下でプログラム開発を行っています。TextBoxで数値のみ入力可能にする方法を教えてください。

Aベストアンサー

private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if(!('0' <= e.KeyChar && e.KeyChar <= '9'))
e.Handled=true;
}
keyPressイベントで
Handled に true を設定すれば、キャンセルできます。
小数点のチェックを入れる場合は、チェックをもう少し考えないといけません


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング