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

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

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

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

4回答

12156閲覧

別フォームでのイベントを他のフォームで処理したい?

yal

総合スコア41

C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2021/09/23 02:18

編集2021/09/23 12:56

前提・実現したいこと

サブのformでボタンをクリックなどのイベントを起こしたら,
メインのformで処理を行いたいです.
インスタンス生成してサブの変数をメインで使うことができますが,
メインのformでサブformでイベントが起きたことを受け取れなくて困っています.
ご助言よろしくお願いします.

追記です。
fanaさんのmainフォームで関数を書いて、subフォームでボタンが押されるイベントと紐付けた関数がmainの関数を呼び出して処理するという方法でできました。

皆様ありがとうございます。
一応できたのですが、
しかし、お二人のsubフォームのボタンのModifiersをpublicにして
mainフォームに書いてある関数にクリックイベントを紐付けるっていうのができないのですが、
これはインスタンスに失敗しているのでしょうか。
プロパティのイベントにmainフォームに書いた関数が現れません...
コードですべて紐付けているのでしょうか...?

発生している問題・エラーメッセージ

該当のソースコード

C#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using System.Data.SQLite; 11using System.Diagnostics; 12using System.Text.Json; 13 14namespace cs_launcher_1 15{ 16 public partial class murrelet : Form 17 { 18 public static DataTable dataTable = new DataTable(); 19 subF subF = new subF(); 20 21 public murrelet() 22 { 23 InitializeComponent(); 24 25 } 26 27 private void murrelet_Load(object sender, EventArgs e) 28 { 29 this.Text = "murrelet"; 30 using (SQLiteConnection con = new SQLiteConnection("Data Source = test.db")) 31 using (SQLiteDataAdapter adapter = new SQLiteDataAdapter("SELECT * FROM food", con)) 32 { 33 adapter.Fill(dataTable); 34 dataGridView1.RowHeadersVisible = false; 35 dataGridView1.Columns[0].Visible = false; 36 dataGridView1.Columns[6].Visible = false; 37 con.Close(); 38 } 39 } 40 41 42 43 public void esidButton_click(object sender,EventArgs e) 44 { 45 this.subF.esid = this.esidAdd.textBox1.Text; 46 this.toolStripStatusLabel1.Text = this.subF.id; 47 48 this.subF.Visible = false; 49 } 50 51 public void button1_Click(object sender,EventArgs e) 52 { 53 esidAdd.button1.Click += mainF; 54 } 55 56 public void mainF(object sender,EventArgs e) 57 { 58 this.toolStripStatusLabel1.Text = "検知成功"; 59 } 60 61 public static void TheProcess() 62 { 63 Console.WriteLine("成功"); 64 } 65 } 66}

試したこと

入門の本やネットで調べたりしたのですが,よくわかりませんでした.
メインのフォームに関数を書くのが正解なのでしょうか.

補足情報(FW/ツールのバージョンなど)

Windows 10 Home 20H2
VisualStudioVersion = 16.0.31624.102
C#
.NET framework 4.7.2

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/09/23 02:23

ごく簡単なサンプルで良いので、「別フォームでのイベントを他のフォームで処理」するために自分で考えてやったこと、それでどこがどのように期待と異なるのかを、コードを示して説明できませんか?
退会済みユーザー

退会済みユーザー

2021/09/23 13:03

今頃出てきて何を言ってるのでしょう? > fanaさんのmainフォームで関数を書いて、subフォームでボタンが押されるイベントと紐付けた関数がmainの関数を呼び出して処理するという方法でできました。 であれば fana さんの回答にベストアンサーを付けてこのスレッドはクローズすべき。本題とは別の質問は、新たに別のスレッドを立てて質問してはいかが?
yal

2021/09/23 14:13

そうですね。ありがとうございます
guest

回答4

0

一番実装が楽なのは、既に回答されているSubFormのコントロールに対してイベントハンドラを設定する方法です。

もしSubFormの機能・やりとりするデータの仕様が確定しているならば、独自のカスタムイベントを作成するという方法もあります。

.NET ガイドラインに準拠したイベントを発行する方法 (C# プログラミング ガイド)

例えば、SubFormの機能がボタンでじゃんけんの手を選んで返すものだとしたら、

cs

1using System; 2using System.Windows.Forms; 3 4namespace WindowsFormsApp2 5{ 6 public partial class SubForm : Form 7 { 8 public event EventHandler<JankenEventArgs> JankenHandSelected; 9 10 public SubForm() 11 { 12 InitializeComponent(); 13 } 14 15 private void buttonGuu_Click(object sender, EventArgs e) 16 { 17 OnJankenHandSelected(new JankenEventArgs(JankenHand.Guu)); 18 } 19 20 private void buttonCyoki_Click(object sender, EventArgs e) 21 { 22 OnJankenHandSelected(new JankenEventArgs(JankenHand.Cyoki)); 23 } 24 25 private void buttonPaa_Click(object sender, EventArgs e) 26 { 27 OnJankenHandSelected(new JankenEventArgs(JankenHand.Paa)); 28 } 29 30 protected virtual void OnJankenHandSelected(JankenEventArgs e) 31 { 32 var handler = JankenHandSelected; 33 if( handler!=null ) 34 { 35 handler(this, e); 36 } 37 } 38 } 39 40 public enum JankenHand 41 { 42 Guu, 43 Cyoki, 44 Paa 45 } 46 47 public class JankenEventArgs : EventArgs 48 { 49 public JankenEventArgs(JankenHand hand) => Hand = hand; 50 51 public JankenHand Hand { get; set; } 52 } 53}

こんな感じで実装すると、SubFormのグー、チョキ、パーのボタンを押した時にJankenHandSelectedイベントイベントが発生します。MainForm側でイベントハンドラを追加して、じゃんけんの選択結果を受け取る事が出来ます。

using System; using System.Windows.Forms; namespace WindowsFormsApp2 { public partial class FormMain : Form { private SubForm _SubForm = new SubForm(); public FormMain() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); _SubForm.JankenHandSelected += OnJankenHandSelected; _SubForm.Show(this); } private void OnJankenHandSelected(object o, JankenEventArgs e) { label1.Text = e.Hand.ToString(); } } }

(実行結果)
実行結果

SubFormのコントロールに直接イベントハンドラを設定するより実装は手間が掛かりますが、SubForm側で操作しているコントロールをMainForm側で意識させたくない場合は有効です。

投稿2021/09/23 12:41

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

既にある別の回答の方法でも基本的に問題ないけど

サブのformでボタンをクリックなどのイベントを起こしたら,
メインのformで処理を行いたいです.

をストレートにやるなら

  1. 公開したいサブFormのボタンでModifiersプロパティをPublicに変更
  2. メインFormでサブFormのインスタンスを生成したら、ボタンコントロールに直接アクセスできるので、イベントハンドラをセットする

だけ。

###追記

しかし、お二人のsubフォームのボタンのModifiersをpublicにして

mainフォームに書いてある関数にクリックイベントを紐付けるっていうのができないのですが、
これはインスタンスに失敗しているのでしょうか。
プロパティのイベントにmainフォームに書いた関数が現れません...
コードですべて紐付けているのでしょうか...?

日本語としてイマイチ理解できない部分が多いけども…。
とりあえず「これはインスタンスに失敗しているのでしょうか。」は意味不明。
インスタンスは動詞じゃないので失敗する、という表現をされても何が言いたいのかわからない。

「プロパティのイベントにmainフォームに書いた関数が現れません...」
「コードですべて紐付けているのでしょうか...?」

これについては、おそらく根本的な勘違いをしてると思うけど、デザイナ上での作業はSubフォームのModifiersプロパティをPublicに変更することだけ。

イベントハンドラをセットするという作業は、MainフォームでSubフォームのインスタンスを生成した際に、コードビハインドで行えばいいだけ。(ここは別回答にもあるんで省略)

投稿2021/09/23 02:52

編集2021/09/23 22:48
gentaro

総合スコア8949

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

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

fana

2021/09/23 04:10

確かに,最も直通な方法を示すとしたらこうなりますね.
guest

0

ベストアンサー

メインのformで処理を行いたいです.

というのは,メイン側のformのクラスのメソッドに処理を実装するって話ですよね.

CSharp

1public partial class MainForm : Form 2{ 3 public TheProcess(){ /*何か処理するぜ!*/ } 4}

で,サブ側のFormでボタンを押したときのイベントハンドラは以下のような形.

CSharp

1public prtial class SubForm : Form 2{ 3 private void button1_Click(object sender, EventArgs e) 4 { /*ここに処理を書く*/ } 5}

であれば,「/ここに処理を書く/」の部分で, MainForm.TheProcess を呼び出せば良いですよね.
(そのためには,MainForm のインスタンスへの参照を SubForm が知っていれば良いですよね)

あるいは,何かしらの経路をめぐりめぐって結果として MainForm.TheProcess が呼び出されるようにすれば良いですよね.
(そのために必要な何かを SubForm が知っていれば良いですよね)

投稿2021/09/23 02:31

fana

総合スコア11658

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

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

0

基本的には gentaro さんの案と同じですが・・・

デザイナで Form にドラッグ&ドロップしたコントロールは .Designer.cs では private で、それを書き換えたくないという場合は、Form は partial なのでそれにアクセスできるパブリックプロパティを定義して使えます。

SubForm のデザイナ画面で Button をドラッグ&ドロップしたとして、SubForm.cs で以下のようにそれにアクセスできるパブリックプロパティ ButtonOnSubForm を定義します。

using System.Windows.Forms; namespace WinFormsApp2 { public partial class SubForm : Form { public SubForm() { InitializeComponent(); } public Button ButtonOnSubForm { get { return this.button1; } } } }

MainForm では以下のようにアクセスして、その Click イベントにイベントハンドラを設定できます。インテリセンスは働きますし、ハンドラの自動生成もできます。

using System; using System.Windows.Forms; namespace WinFormsApp2 { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { SubForm subFrom = new SubForm(); subFrom.ButtonOnSubForm.Click += ButtonOnSubForm_Click; subFrom.Show(); } private void ButtonOnSubForm_Click(object sender, EventArgs e) { this.label1.Text = "Button on SubForm Clicked!"; } } }

実行結果は:

イメージ説明

投稿2021/09/23 09:41

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

YAmaGNZ

2021/09/23 09:55

勘違いなら申し訳ありませんが、Modifiersプロパティはデザイナで変更可能です。 それも .Designer.csを書き換える行為と言ってしまえばそうなのですが、仰っているのは .Designer.csを手動で変更するという意味合いかと思ったんで。
退会済みユーザー

退会済みユーザー

2021/09/23 10:22

> Modifiersプロパティはデザイナで変更可能です。 確かにそうですね。正直初めて知りました。 でも、自分はデフォルトから変えない派ですので、上に紹介した方法でやってます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問