C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: フラグが変化したときに発生するイベントを作りたい


(過去ログ 173 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■99448 / inTopicNo.1)  フラグが変化したときに発生するイベントを作りたい
  
□投稿者/ あいす (1回)-(2022/04/12(Tue) 17:26:21)

分類:[C#] 

C#でボタンをクリックしたら発生するイベントのように自分が用意したフラグが変化したら発生するイベントを作りたいのですがどのようにすればいいのでしょうか。
初歩的な質問ですみません。
引用返信 編集キー/
■99449 / inTopicNo.2)  Re[1]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ 魔界の仮面弁士 (3316回)-(2022/04/12(Tue) 18:12:57)
No99448 (あいす さん) に返信
> C#でボタンをクリックしたら発生するイベントのように
> 自分が用意したフラグが変化したら発生するイベントを
> 作りたいのですがどのようにすればいいのでしょうか。

フラグは変数ではなくプロパティとして実装しておけば、
setter によって「フラグが変更された時」を捕らえる事ができますね。

プロパティの代わりに、「フラグを更新するためのメソッド」を作る方法でも良いですが。


肝心のイベントの宣言は、自作クラス内で
「public event EventHandler YourEventName;」
のようにすれば OK。

作ったイベントを発生させるのは
 YourEventName?.Invoke(this, EventArgs.Empty);
という構文です。


たとえば上記を内部から呼びやすくするため、
 protected virtual void OnYourEventName(EventArgs e)
 {
  YourEventName?.Invoke(this, e);
 }
などを用意しておき、「フラグが変化した時」に、自クラスまたは継承クラスから
『OnYourEventName(EventArgs.Empty);』で呼び出すようにします。


イベントの利用側は、ボタンクリックの
 button1.Click += ……;
と同様に、
 foo.YourEventName += ……;
のように割り当てて使います。


もしもイベント引数に追加情報を持たせい場合には、
「EventArgs を継承した、自作の HogeEventArgs クラス」を作り、
そこに追加のプロパティやメソッドを実装し、下記のように変更します。


//public event EventHandler YourEventName;
public event EventHandler<HogeEventArgs> YourEventName;
引用返信 編集キー/
■99450 / inTopicNo.3)  Re[2]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ kiku (255回)-(2022/04/13(Wed) 09:28:09)
No99449 (魔界の仮面弁士 さん) に返信
> ■No99448 (あいす さん) に返信
>>C#でボタンをクリックしたら発生するイベントのように
>>自分が用意したフラグが変化したら発生するイベントを
>>作りたいのですがどのようにすればいいのでしょうか。
> 
> フラグは変数ではなくプロパティとして実装しておけば、
> setter によって「フラグが変更された時」を捕らえる事ができますね。

魔界の仮面弁士さんからご説明頂いたことを
そのままソースにするとこんな感じになります。

    public partial class Form1 : Form
    {
        TestClass testClass;
        public Form1()
        {
            InitializeComponent();
            testClass = new TestClass();
            testClass.YourEventName += TestClass_YourEventName;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            testClass.TestFlag = true;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            testClass.TestFlag = false;
        }
        private void TestClass_YourEventName(object sender, TestClass.HogeEventArgs e)
        {
            if (e.TestFlag)
            {
                label1.Text = "true";
            }
            else
            {
                label1.Text = "false";
            }
        }
    }

    class TestClass
    {
        public class HogeEventArgs : EventArgs
        {
            public HogeEventArgs(bool testFlag)
            {
                TestFlag = testFlag;
            }
            public bool TestFlag { set; get; }
        }
        public event EventHandler<HogeEventArgs> YourEventName;
        protected virtual void OnYourEventName(HogeEventArgs e)
        {
            YourEventName?.Invoke(this, e);
        }
        private bool _TestFlag = false;
        public bool TestFlag
        {
            set {
                this._TestFlag = value;
                OnYourEventName(new HogeEventArgs(this._TestFlag));
            }
            get { return this._TestFlag; }
        }
    }

引用返信 編集キー/
■99451 / inTopicNo.4)  Re[3]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ あいす (2回)-(2022/04/13(Wed) 11:28:04)
No99450 (kiku さん) に返信
> ■No99449 (魔界の仮面弁士 さん) に返信

ご教授ありがとうございます。

フラグをForm1以外でも変更し、それを検出したいのですがその際にはどのようにすればいいのでしょうか。
変更したいファイルで TestClass testClass; を宣言し testClass.TestFlag = true;にしてもlabelが変わらなかったので、、
引用返信 編集キー/
■99452 / inTopicNo.5)  Re[4]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ kiku (256回)-(2022/04/13(Wed) 11:38:36)
No99451 (あいす さん) に返信
> ■No99450 (kiku さん) に返信
>>■No99449 (魔界の仮面弁士 さん) に返信
>
> ご教授ありがとうございます。
>
> フラグをForm1以外でも変更し、それを検出したいのですがその際にはどのようにすればいいのでしょうか。
> 変更したいファイルで TestClass testClass; を宣言し testClass.TestFlag = true;にしてもlabelが変わらなかったので、、

上記「Form1以外」とはどういうことなのか?を説明頂けないと返答できないと思います。
もしくは
それを検証できる最低限のソースを提示するなど。
引用返信 編集キー/
■99453 / inTopicNo.6)  Re[4]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ radian (27回)-(2022/04/13(Wed) 11:49:27)
2022/04/13(Wed) 11:55:34 編集(投稿者)

> フラグをForm1以外でも変更し、それを検出したいのですがその際にはどのようにすればいいのでしょうか。
> 変更したいファイルで TestClass testClass; を宣言し testClass.TestFlag = true;にしてもlabelが変わらなかったので、、

ソース提示されてないから想像ですが、TestClassのインスタンスが別になってませんか?
別の場所でTestClassをnewしたところで、イベントハンドラの設定されていないTestClassが作成されるだけですよ。
TestClassをシングルトンにするか、TestClassのインスタンスを何らかの方法で共有するなりしないといけないでしょうね。
引用返信 編集キー/
■99454 / inTopicNo.7)  Re[5]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ あいす (4回)-(2022/04/13(Wed) 12:01:15)
No99452 (kiku さん) に返信
> ■No99451 (あいす さん) に返信
>>■No99450 (kiku さん) に返信
> >>■No99449 (魔界の仮面弁士 さん) に返信
>>
>>ご教授ありがとうございます。
>>
>>フラグをForm1以外でも変更し、それを検出したいのですがその際にはどのようにすればいいのでしょうか。
>>変更したいファイルで TestClass testClass; を宣言し testClass.TestFlag = true;にしてもlabelが変わらなかったので、、
>
> 上記「Form1以外」とはどういうことなのか?を説明頂けないと返答できないと思います。
> もしくは
> それを検証できる最低限のソースを提示するなど。

言葉足らずですみません。
Form1とは別のフォームでも対象のフラグを変更できるようにし、その変更検出をForm1でしたいです。

引用返信 編集キー/
■99455 / inTopicNo.8)  Re[4]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ 魔界の仮面弁士 (3317回)-(2022/04/13(Wed) 12:06:01)
No99451 (あいす さん) に返信
> フラグをForm1以外でも変更し、

そのフラグを Form1 で管理しているのなら、
Form1.cs で internal あるいは public で公開すれば、
他のフォームからでも、Form1のインスタンスのメンバーとして変更できるようになります。

Form1 のインスタンスメンバーとしたいのではなく、
プロジェクト全体で単一的に使う物なら、Program.cs で public static にしておけば、
Program.何某〜〜 としてアクセスできます。
あるいはシングルトンクラスを用意するということも出来るでしょう。


アプリケーション設定、たとえば
 Properties.Settings.Default.MyFlag = "何某";
などを使っているのであれば、さらに話は簡単で、
PropertyChanged イベントがそのまま変更通知として使えるので
自分でイベントを自作する必要すらありません。

[STAThread]
static void Main()
{
  Properties.Settings.Default.PropertyChanged += (sender, e) =>
  {
    System.Diagnostics.Debug.WriteLine("{0}:{1}", e.PropertyName, Properties.Settings.Default[e.PropertyName]);
    if (e.PropertyName == "MyFlag")
    {
      MessageBox.Show("MyFlagが変更された");
    }
  };
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new Form1());
}



> 変更したいファイルで TestClass testClass; を宣言し
> testClass.TestFlag = true;にしてもlabelが変わらなかったので、、

kiku さんのサンプルで言うと、
 public partial class Form1 : Form
 {
   private TestClass testClass;
 }
という状態になっているので、Form1 以外からは操作できません。


(案1) アクセス修飾子を、private から internal に格上げする
 public partial class Form1 : Form
 {
   internal readonly TestClass testClass = new TestClass();
 }


(案2) インスタンスそのものは公開せず、フラグ操作部だけを公開する
 public partial class Form1 : Form
 {
   private readonly TestClass testClass = new TestClass();
   public void ChangeFlag(bool newValue)
   {
     testClass.TestFlag = newValue;
   }
 }

Form1 のインタンス メンバーを別フォームからアクセスしたい場合は、
Form1 から他フォームを開く際に、Form1 の this を他フォームに受け渡しておくのが
手っ取り早いでしょう。(たとえば Owner プロパティに渡すこともできます)。

あるいは、Application.OpenForms を通じて動的に取得するということもできます。
引用返信 編集キー/
■99456 / inTopicNo.9)  Re[5]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ kiku (257回)-(2022/04/13(Wed) 12:47:51)
No99455 (魔界の仮面弁士 さん) に返信
> ■No99451 (あいす さん) に返信
> (案2) インスタンスそのものは公開せず、フラグ操作部だけを公開する
>  public partial class Form1 : Form
>  {
>    private readonly TestClass testClass = new TestClass();
>    public void ChangeFlag(bool newValue)
>    {
>      testClass.TestFlag = newValue;
>    }
>  }

案2でサンプル書いてみました。

    public partial class Form1 : Form
    {
        private TestClass testClass;
        private Form2 form2;
        public Form1()
        {
            InitializeComponent();
            testClass = new TestClass();
            testClass.YourEventName += TestClass_YourEventName;
            form2 = new Form2();
            form2.Show(this);
        }
        public void SetFlag(bool flag)
        {
            testClass.TestFlag = flag;
        }
        private void TestClass_YourEventName(object sender, TestClass.HogeEventArgs e)
        {
            if (e.TestFlag)
            {
                label1.Text = "true";
            }
            else
            {
                label1.Text = "false";
            }
        }
    }

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            ((Form1)Owner).SetFlag(true);
        }
        private void button2_Click(object sender, EventArgs e)
        {
            ((Form1)Owner).SetFlag(false);
        }
    }

    class TestClass
    {
        public class HogeEventArgs : EventArgs
        {
            public HogeEventArgs(bool testFlag)
            {
                TestFlag = testFlag;
            }
            public bool TestFlag { set; get; }
        }
        public event EventHandler<HogeEventArgs> YourEventName;
        protected virtual void OnYourEventName(HogeEventArgs e)
        {
            YourEventName?.Invoke(this, e);
        }
        private bool _TestFlag = false;
        public bool TestFlag
        {
            set {
                this._TestFlag = value;
                OnYourEventName(new HogeEventArgs(this._TestFlag));
            }
            get { return this._TestFlag; }
        }
    }

引用返信 編集キー/
■99471 / inTopicNo.10)  Re[6]: フラグが変化したときに発生するイベントを作りたい
□投稿者/ ぶなっぷ (284回)-(2022/04/15(Fri) 10:23:16)
途中からなので、あいすさんの意図を理解できているか怪しいですが ^^;

> 変更したいファイルで TestClass testClass; を宣言し testClass.TestFlag = true;にしてもlabelが変わらなかったので、、
これって、いわゆるバインディングを意識してますか?
データの値を変えると、即座に(メソッドを呼ばなくても)GUIが変化します。

Form, WPFどちらでもできます。

[Form]
https://work-professor.org/?p=626

[WPF]
https://atmarkit.itmedia.co.jp/ait/articles/1010/08/news123.html

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -