質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

3回答

1203閲覧

別FormのPropertyの変化を知りたい

cancat

総合スコア313

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2017/10/25 11:31

編集2022/01/12 10:55

こんにちは。
Windows10でWindows Formのアプリケーションを開発しています。
Visual Studio 2017 Communityを使っています。

###前提・実現したいこと
FormAからFormBを別ウィンドウでモードレスで開いています。
FormBのプロパティ(Message)の変更をFormAで取得するには、どのようにしたらよいですか?

###発生している問題・エラーメッセージ
FormBのPropertyの変更を取得できない。

###該当のソースコード

c#

1FormA 2 public FormA() 3 { 4 InitializeComponent(); 5 FormB formB = new FormB(); 6 }
FormB private string message = ""; public string Message { get => message; set => message = value; } public FormB() { InitializeComponent(); }

###補足情報(言語/FW/ツール等のバージョンなど)
Microsoft Visual Studio Community 2017
Version 15.0.26228.9 D15RTWSVC
Microsoft .NET Framework
Version 4.6.01586

です。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

class FormA:Form { public FormA() { InitializeComponent(); FormB formB = new FormB(); formB.MessageChanged = (message)=>{ 変更された後すること}; } }
class FormB:Form { public FormB() { InitializeComponent(); } public Action<string> MessageChanged {get;set;} private string message = ""; public string Message { get => message; set { if (message != value) { message = value; MessageChanged?.invoke(message) } } } public FormB() { InitializeComponent(); }

イベントを使うと、複数の変更通知を行えるのですが、Actionを使うと、一つのところにしか対応しない。
でも、実際、一つで充分だったりする、という話ですね。

オブジェクトに対して、ActionやFuncを差し込んで連携させるというのは、よくやります。

投稿2017/11/05 05:30

kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

訂正:完全に勘違いのコメントしちゃいました。お恥ずかしい限りです。失礼しました。


FormAからFormBを呼んだとき

FormAのメソッドでFormBをモーダル表示するという意味なら

C#

1public class FormA : Form { 2 ... 3 void Button1Click(...) { 4 var formb = new FormB(); 5 formb.Message = "メッセージ"; 6 formb.ShowDialog(this); 7 ... 8 } 9}

「FormBを呼ぶ」ではなく「FormAからFormBをモーダル表示する/モードレス表示する」というような表現の方が正確に意味が通じると思います。

投稿2017/10/25 11:52

編集2017/10/25 11:53
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cancat

2017/10/25 12:04

質問を修正しました。コメントありがとうございます。
guest

0

INotifyPropertyChanged を使えばいいじゃん。
どういう仕組で、WPFのBindができているかを真似すればいいよ。

PropertyChangedは、イベントなのよ。イベントは、C#の解説書にでてくることよ。

投稿2017/10/25 11:38

編集2017/10/25 11:41
kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cancat

2017/10/25 11:53

コメントありがとうございます。 FormBはFormを継承しているので、INotifyPropertyChangedを継承できない気がします。 FormBにPropertyChangedメソッドを実装しても、FormAでは知りようがない気がします。
kiichi54321

2017/10/25 11:58 編集

class FormB:Form,INotifyPropertyChanged{} でいいのでは?インターフェースはできますよ。 あと、FormA側で、FormBのPropertyChangedのイベントを登録するのですよ?
cancat

2017/10/25 12:08

FormA側で、FormBのPropertyChangedのイベントを登録するのはどのようにするのでしょうか?
kiichi54321

2017/10/25 12:13

FormB formB = new FormB();fromB.PropertyChanged+=(o,e) =>{変更が起きたときやること。} 基本・・
KSwordOfHaste

2017/10/25 12:36

横から失礼いたします。アホな回答を付けてしまってすみません。 INotifyPropertyChangedを学ぶのがまず基本であると思いますが、若干実装側が面倒なため、ReactivePropertyなど他の機構を用いる選択肢もあるかと思います。以下をみてそういうのもあるのだなぁと思いました。 https://qiita.com/ledsun/items/6f4ef754e5ae2507e531
cancat

2017/10/25 13:08

kiichi54321さん、ありがとうございます。ふとむずかしく考えずに、単にFormAでイベントハンドラを実装すればいいんじゃんと思い至り実装してみました。が、Bでプロパティの値が変わっても、AのほうのPropertyChangedメソッドには飛んでこないです。なぜ飛んでこないんでしょう? KSwordOfHasteさん、いろいろありがとうございます。MVVMとINotifyPropertyChangedは何度か学ぼうとして失敗していて、やっといまちょっと意味がわかってきた感じです。たしかにほかの機構を用いるのもありですね。情報サンクス。
kiichi54321

2017/10/25 13:45 編集

PropertyChanged?.Invoke をしていないだけのような。構文が増えて、昔ほど面倒ではなくなったのですが、 実際はrxの方が、イベントの削除周りもやってくれるので、rxの方がいいのですけどね。 一応、そのままだと、formAがなくなった状態で、fromBの値を変更すると、ぬるぽあたりで、落ちます。 参考: http://ufcpp.net/study/csharp/MiscEventSubscribe.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問