お世話になります。
.NET C#で開発をしている初心者です。
親Form1のReadOnlyにしているtextBox1をダブルクリックしたら、子Form2が表れ、
その中で、ラジオボタンなどで各項目を選択する様になっており、選択した結果の
文字列が、子Form2のReadOnlyにしているtextBox1に表示され、これで良ければ、
決定ボタンであるButton1を押すと、子Form2が閉じられ、元の親Form1のReadOnly
にしているtextBox1に子Form2で決定した文字列が表示される様にしたいのですが、
私がやってうまく行かないのは、子Form2で決定した文字列をClassでsetし、親Form1
に制御が移った時に、classからgetしようとしたのですが、
まず、子Form2が閉じられた時、親Form1はtextBox1にダブルクリックしたままの(後の)
状態、つまりカーソルが残ってる状態で、文字列が表示されない。
子Form2が閉じられた時すぐかもしくは、子Form2の決定ボタンであるButton1を押した
時すぐに親Form1のtextBox1に文字列が表示されていて欲しいのですが、その方法が
分からないので、とりあえず、親Form1のtextBox1のLeaveイベントを発生させて文字列
を表示しています。
どなたかご親切な方、ご教授下さいます様、宜しくお願い申し上げます。
No.11ベストアンサー
- 回答日時:
あー、すみません、そこ間違ってました。
親フォームの「オブジェクト」が必要なので、こんな感じになります。
便宜上、親フォームのクラス名をparentForm、子フォームのクラス名をchildFormとしますので適宜読み替えてください。
子フォーム側:
class childForm
{
...
parentForm parent; // 親フォームの参照
public void setParent(parentForm parent)
{
// 親フォームから参照を受け取って保持する
this.parent = parent;
}
...
{
// 親フォームの関数を呼び出す
parent.ctlFromChild("文字列");
}
...
}
親フォーム側:
class parentForm
{
...
childForm child;
{
child = new childForm(); // 子フォーム作成
// 子フォームに自分のオブジェクト参照を渡す
child.setParent(this);
}
...
}
本当はコールバック関数をデリゲートで渡してやる方が筋はいいと思うんですが、今回はこれでOKかと。
上記では親フォームのオブジェクトを登録する関数を作っていますが、コンストラクタで実装してもOKです。
あと、申し訳ないのですがこれは動作試験してないので、これで駄目なら上記の「コールバック関数をデリゲートで渡す」方を紹介します。
長い間この初心者の私にお付き合い下さり、
誠に感謝致します。
おかげさまで、
>// 親フォームの関数を呼び出す
> parent.ctlFromChild("文字列");
部分を
parent.changeTaxtBo1("文字列");
に変えたらエラーが解消され、
子フォームのテキストボックスに書いた文字列が、
親フォームのテキストボックスに反映される事が
出来ました。
ただThreadや、Invokeなどの意味はまだ今一分からない
のでゆっくり勉強しようと思います。
本当に有難うございました。
今後とも宜しくお願い致します。
No.10
- 回答日時:
んー、#9でもタイプミスを指摘してるんですからそれを疑ってほしかった。
正直このレベルの確認を怠って「何故?」と聞かれるのは非常に悲しいです。
> new T"h"readStart
です。hが足らない。
大変お恥ずかしい限りでございます。
わたしも悲しくなってきました。
hを足した事で、親フォームのエラーはなくなりました。
最初の頃に頂きましたご回答で
>子フォームからは任意のタイミング(質問の場合は子フォームの
>OnCloseイベントハンドラ中)でparentForm.changeTextBox1を
>呼び出すことで親のtextBox1が書き換わります。
こうありましたが、、
子フォームから「 親フォーム名.changeTextBox1」 を呼び出して
もエラー(「静的でないフィールド、メソッド、・・・・で、
オブジェクトが必要です。」)になるのは、
今では記述内容が変わってしまったからでしょうか。
No.9
- 回答日時:
……って違う。
自力でタイプするのはいいんですが、間違いなくやるようにしてください。
カッコのエラーは、こちらで提示したコードが
> Invoke((ctlFromChild)delegate
であるのに対して、エラーが出ているのは
> Invoke((ctlFromChild)(delegate
となると、delegate前の(を取るのが正しいです。
大変失礼いたしました。
delegate前の(は取りました。
> 型または名前空間名 'TreadStart' が見つかりませんでした
で何が足りないかは、「using System.Threading;」は追加しましたし、
何が足りないんだろう。
すいません、分かりません。
No.8
- 回答日時:
カッコの不足分についてはそれであってます。
というか欠けてましたか、すみません。
> 型または名前空間名 'TreadStart' が見つかりませんでした
先の回答で提示した該当部分は
> new ThreadStart
です。さて何が足りないでしょう?
No.7
- 回答日時:
お待たせしました。
別解です。System.Threadingを使うので、別途using宣言してください。
デリゲート宣言からやりなおします。
private delegate void ctlFromChild();
public void changeTextBox1(string str)
{
new Thread(new ThreadStart(
delegate {
Invoke((ctlFromChild)delegate
{
textBox1.Text = str;
});
})).Start();
}
動いているコードから引っ張ってきたものなので、これならたぶん大丈夫じゃないかと。
いつもお世話になっております。
「 )がありません。」とエラーが出ていましたので、下記記述
「Invoke((ctlFromChild)(delegate
{
textBox8.Text = str;
});」
の中の最後に「}));」付け足しました。合っていますでしょうか。
また、
「new Thread(new TreadStart(delegate」の「TreadStart」部分に
赤い下波線が有り、「型または名前空間名 'TreadStart' が見つかりません
でした。using ディレクティブまたはアセンブリ参照が不足しています。」
と出ています。
今回「using System.Threading;」は追加しております。
どこが悪いでしょうか。
No.6
- 回答日時:
難しいっつーか面倒なだけなんですけどね。
アクセス制限ということなら関数にpublic宣言が入ってないせいかとも思いますが、昨日別解を掘り起こしたので帰宅したらそちらのコードも提示しますね。
まぁ別解とは言っても、デリゲートを使ってるという点では一緒なんですが。
No.5
- 回答日時:
えーと、私も最近C#を使ってないので色々抜けてるようです。
静的関数ではないためにオブジェクトが要るので、引数changeTextBox1delの頭にthis.を付けてみてください。
それで駄目ならthisの代わりに親フォームの名前を。
お世話になっております。
すみません。先程の「静的な・・・」と言うエラーメッセージ内容は、
子Formの呼び出し側の方でした。
呼び出すメソッド名の頭に、親フォーム名を付けました。そうしましたら、
おそらく親Formの下記記述部分でエラーが出ている為に、
「アクセスできない保護レベルになっています。」と出ました。
親Formの
「Invoke(new ctlFromChild(changeTextBox1del(str)));」
のchangeTextBox1del(str)に赤い下波線が出ていたエラー内容は、
「メソッド名が必要です。」でした。
メソッドと思われていないと言う事でしょうか。
デリゲートって難しいですね。
No.3
- 回答日時:
ctlFromChildは「親フォーム内」に定義する「デリゲート」であってクラスではありませんから、「子フォーム名」に置き換えてはいけません。
まぁ同じにしてあれば何かと被らない限りはどんな名前にしてもいいんですが。#2での提示部分はそのまま使えるように書いたつもりなので、とりあえずは書き換えせずにやってみてください。
一方で「parentForm」については親フォーム名に置き換えてもらっていいというか、置き換えてもらわなければいけません。
お世話になっております。
何度もすみません。
そのまま記述追加致しましたが、
「delegate ctlFormChild(string str);」の「(」カッコの部分と、
「Invoke(new ctlFormChild(change・・・)」の「ctlFormChild」の
部分に赤い下波線が出てモジュールエラーとなってしまいました。
No.2
- 回答日時:
まず子フォームのクラスメンバ変数にTextbox型の変数を追加します。
で、子フォームの作成時にでも親フォームから自身のtextBox1を渡してやり、子フォームでは上記メンバ変数に格納します。
上記で受け渡したものは参照として機能し、子フォームから親フォームのtextBox1を任意のタイミングで操作出来るようになります。
……って思ったんですが、よくよく考えると今回は別にtextBox1の参照持ってる必要はないですね。失礼しました。
親フォーム側に文字列型を投げるとtextBox1を変更するパブリックメンバ関数を用意しておいて、その中でデリゲートで処理を委譲するようにして子フォームからこのパブリックメンバ関数を呼べばいいです。
親フォーム側:
class parentForm {
// 記述追加
delegate ctlFromChild(string str);
public void changeTextBox1(string str)
{
Invoke(new ctlFromChild(changeTextBox1del(str)));
}
void changeTextBox1del(string str)
{
this.textBox1.text = str;
}
};
上記処理を追加しておいて、子フォームからは任意のタイミング(質問の場合は子フォームのOnCloseイベントハンドラ中)でparentForm.changeTextBox1を呼び出すことで親のtextBox1が書き換わります。
なんでこう書く必要があるのかは先に提示したURLを読んでください。
なお、複数のテキストボックスを汎用的に扱いたい場合は、最初に言ったように操作対象のコントロールの参照を持っておくとコードが共通化できて見通しが良くなります。
ご丁寧に有難うございます。
しかし、私のスキル不足のよりモジュールエラーが出ており、
何度も申し訳ございませんが、再度ご確認させて頂きたく、
宜しくお願い致します。
確認1
「delegate ctlFromChild(string str);」と
「Invoke(new ctlFromChild(changeTextBox1del(str)));」に
出てくる「ctlFromChild」は、実際の子フォーム名に置き換えて
良いのですよね。
確認2
「Invoke(new ctlFromChild(changeTextBox1del(str)));」
の「(changeTextBox1del(str)」の部分に赤い下波線が出ており、
メソッド名が必要です。と言うモジュールエラーが出てしまっています。
何かが間違い又は不足でしょうか。
確認3
子フォームの呼び出しのコードを下記の様に書いたのですが、
間違ってますでしょうか。「Form1.changeTextBox8(mojiretu)」
と言う所に赤い下波線が出てしまっていて、
「静的でないフィールド、メソッド、またはプロパティに含まれていないため、
コードの解析または生成をサポートしません。」と言うモジュールエラー
が出てしまっているのですが。
string mojiretu;
mojiretu = textBox1.Text;
Form1.changeTextBox8(mojiretu);
↑実際の親フォーム名 ↑実際の親フォームテキストボックス
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
指定の動作中ユーザーフォーム...
-
ExcelVBAのユーザーフォームの...
-
VBでフォームのイメージを印...
-
ユーザーフォームを表示中にシ...
-
MSGBOXのフォント大きさ変更
-
Excelにて、ユーザーフォームで...
-
VB.netでフォームのクローン
-
ACCESSのフォーム、開くんです...
-
エクセルのVBAでユーザーフォー...
-
ブックをCloseまたはQuitで閉じ...
-
EXCEL VBA ユーザーフォームの...
-
コントロールの存在確認
-
ユーザーフォームのテキストボ...
-
画像を使った検索フォームの作り方
-
Accessで、一つのフォーム画面...
-
フォームの二重起動の阻止
-
モーダルフォームとモードレス...
-
ExcelVBAでユーザーフォームが...
-
ユーザフォームの印刷
-
ACCESS VBA ウィンドウを閉じる
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ユーザーフォームを表示中にシ...
-
ExcelVBAのユーザーフォームの...
-
ユーザーフォームのテキストボ...
-
エクセルVBAのフォームを最...
-
クリックイベントなのに、2回ク...
-
VBAでユーザーフォームを再表示...
-
Form_Load と Form_Activate の...
-
Microsoft Formsの「個人情報や...
-
ACCESSのフォーム、開くんです...
-
'ユーザーフォーム右上隅の[×...
-
フォームウィンドウを最前面に...
-
Hideについて(.NET)
-
モーダルフォームとモードレス...
-
ユーザーフォーム上に現在日時...
-
MSGBOXのフォント大きさ変更
-
Excelにて、ユーザーフォームで...
-
コントロールの存在確認
-
ユーザーフォームのラベルに時...
-
VBA(エクセル)のユーザー...
-
エクセルVBA フォーム上でOnkey...
おすすめ情報