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

わんくま同盟

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

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

ツリー一括表示

onShown など on〜の使い方 /エベェ (19/06/29(Sat) 09:20) #91453
Re[1]: onShown など on〜の使い方 /WebSurfer (19/06/29(Sat) 09:46) #91454
Re[1]: onShown など on〜の使い方 /魔界の仮面弁士 (19/06/29(Sat) 11:04) #91455
Re[1]: onShown など on〜の使い方 /WebSurfer (19/06/29(Sat) 11:26) #91456
  └ Re[2]: onShown など on〜の使い方 /エベェ (19/06/29(Sat) 14:04) #91458 解決済み


親記事 / ▼[ 91454 ] ▼[ 91455 ] ▼[ 91456 ]
■91453 / 親階層)  onShown など on〜の使い方
□投稿者/ エベェ (1回)-(2019/06/29(Sat) 09:20:01)

分類:[.NET 全般] 

お世話になります

基本的な質問で恥ずかしいのですが
vb.net のコードで「on〜」というコードを見かけるのですが意味がよくわかりません

下記のコードの場合(今編集しているformのコードです)

■イベント1
■イベント2
の両方が実行され

●処理1
●処理3
の両方が実行されると思います

この処理で
「■イベント1(SHOWN)」 と 「■イベント2(onSHOWN)」 を分ける意味がわかりません
「■イベント1(SHOWN)」に「●処理1」と「●処理3」をまとめても同じ結果になるのでしょうか
理由があるとすればどういったことが想定されるのでしょうか
またon〜 どいういった場合に使われるものなのでしょうか

============================================
class名「fm」
System.Windows.Forms.form
============================================
public class fm  
Private Sub fm_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown  '←■イベント1
Me.Size = new size(10,10) '←●処理1
End Sub
Protected Overrides Sub OnShown(ByVal e As EventArgs) '←■イベント2
MyBase.OnShown(e) '←●処理2
Me.Capture = True '←●処理3
End Sub
end class
============================================


[ □ Tree ] 返信 編集キー/

▲[ 91453 ] / 返信無し
■91454 / 1階層)  Re[1]: onShown など on〜の使い方
□投稿者/ WebSurfer (1846回)-(2019/06/29(Sat) 09:46:08)
No91453 (エベェ さん) に返信

System.Windows.Forms 名前空間の Form クラスのことであれば、Shown はイベントで、
OnShown は Shown イベントを発生させるメソッドです。

以下、MSDN ライブラリの抜粋:

Form.OnShown メソッド

Shown イベントを発生させます。
OnShown メソッドを使用すると、デリゲートを結び付けずに、派生クラスでイベントを
処理することもできます。派生クラスでイベントを処理する場合は、この手法をお勧め
します。


Form.Shown イベント
フォームが初めて表示されるたびに発生します。
Shown イベントは、フォームが初めて表示されたときにのみ発生します。それ以降に、
最小化、最大化、元に戻す、非表示にする、表示する、無効にするなどの操作や、再描
画を行っても、このイベントは発生しません。


[ 親 91453 / □ Tree ] 返信 編集キー/

▲[ 91453 ] / 返信無し
■91455 / 1階層)  Re[1]: onShown など on〜の使い方
□投稿者/ 魔界の仮面弁士 (2211回)-(2019/06/29(Sat) 11:04:19)
2019/06/30(Sun) 07:08:07 編集(投稿者)

No91453 (エベェ さん) に返信
> この処理で
> 「■イベント1(SHOWN)」 と 「■イベント2(onSHOWN)」 を分ける意味がわかりません
> 「■イベント1(SHOWN)」に「●処理1」と「●処理3」をまとめても同じ結果になるのでしょうか

そのクラスを継承する場合に差異が生じることになりますね。
(継承を想定していないクラスなら、NotInheritable なクラスとして宣言すべきです)

> またon〜 どいういった場合に使われるものなのでしょうか

そもそも『Sub Onイベント名( e As EventArgs派生クラス )』なメソッドは、
多くの場合、Protected Overidable な
(あるいは単に Protected な)メソッドとして実装されます。
これは、自身が持つイベントを継承先で発生させるために設けられます。


たとえば……クラスが自身のイベントを発生させるために、
RaiseEvent というステートメントが使われますよね。

もしも自作クラスに Code プロパティが設けられていて、
それが変更された時に CodeChanged イベントを発生させたいとしたら、
このようなコードを書くことができます。

Public Event CodeChanged As EventHandler
Public Property Code() As String
 Get
  Return _Code
 End Get
 Set(value As String)
  If _Code <> value Then
    _Code = value
    RaiseEvent CodeChanged(Me, EventArgs.Empty)
  End If
 End Set
End Property
Private _Code AS String


ところがこのような実装ですと、このクラスを継承した新たなクラスを作成する際に都合が悪くなります。
具体的にはこのようなケースです。

「派生クラスから、基本クラスの CodeChanged イベントを意図的に発生させることができない」
「Code が変更された時に、CodeChanged が呼ばれる前に別の処理を割り込ませることができない」
「イベントを発生させることなく Code を書き換える方法が提供されていない」


そこで、イベントを提供するクラスでは、そのイベントを直接 RaiseEvent するのではなく、
RaiseEvent するためのメソッドを設け、それを通じて呼び出されるように実装するのが一般的です。


Protected Overridable Sub OnCodeChanged(e As EventArgs)
 RaiseEvent CodeChanged(Me, EventArgs.Empty)
End Sub

Public Property Code() As String
 Get
  Return _Code
 End Get
 Set(value As String)
  If _Code <> value Then
    _Code = value
    OnCodeChanged(EventArgs.Empty)
  End If
 End Set
End Property

---

このようにデザインしておけば、このクラスを継承する側では、
継承元の Protected Overridable Sub OnCodeChanged(e As EventArgs) を
継承した Protected Overrides Sub OnCodeChanged(e As EventArgs) を通じて、
イベントの発生タイミングを調整することができるというわけです。


派生クラスから、基本クラスの CodeChanged イベントを意図的に発生させるために
 RaiseEvent MyBase.CodeChanged(Me, EventArgs.Empty)
と書くことは文法上許容されていませんが、On何某が用意されていれば、
 OnCodeChanged(EventArgs.Empty)
と書くことで、基本クラスのイベントを意図的に発生させることができます。


Code が変更された時に、CodeChanged が呼ばれる前に別の処理を割り込ませるために、
 Protected Overrides Sub OnCodeChanged(e As EventArgs)
  DoAnything()
  MyBase.OnCodeChanged(e)
 End Sub
のように実装したり、Code を書き換える際のイベントの発生を抑制するために
 Protected Overrides Sub OnCodeChanged(e As EventArgs)
  If CanRaiseEvents Then
   MyBase.OnCodeChanged(e)
  End If
 End Sub
のような条件分岐を行うといったカスタマイズが可能になります。




https://docs.microsoft.com/ja-jp/dotnet/standard/events/

》 通常、イベントを発生させるには、
》 protected や virtual (C# の場合)、または
》 Protected や Overridable (Visual Basic の場合) として
》 マークされたメソッドを追加します。

》 このメソッドには OnEventName の形式で名前を付けます (OnDataReceived など)。

》 メソッドでは、イベント データ オブジェクトを指定するパラメーターを 1 つ受け取る必要があります。
》 これは、EventArgs 型または派生型のオブジェクトです。

》 このメソッドを指定すると、イベントを発生させるためのロジックを
》 派生クラスでオーバーライドできます。

》 派生クラスは常に基底クラスの OnEventName メソッドを呼び出して、
》 登録されたデリゲートがイベントを必ず受信できるようにします。
[ 親 91453 / □ Tree ] 返信 編集キー/

▲[ 91453 ] / ▼[ 91458 ]
■91456 / 1階層)  Re[1]: onShown など on〜の使い方
□投稿者/ WebSurfer (1847回)-(2019/06/29(Sat) 11:26:58)
No91453 (エベェ さん) に返信

参考に、今はリンク切れになったしまった昔の Microsoft のチュートリアルの一部をアッ
プしておきます。(C# ですが)

イベント Changed と、そのイベントを発生させる OnChanged メソッドの使い方が分かる
と思います。

using System;
using System.Collections;

// イベントの宣言には、デリゲートを使用する。イベントが発生すると、クライアントによって
// フックされたデリゲートが呼び出される。

namespace MyEvent
{
    // 宣言されていない場合は、最初にイベントのデリゲート型を宣言する必要がある。sender 
    // はイベントが発生したオブジェクトへの参照。e はイベントデータが格納されているオブ
    // ジェクトへの参照。

    public delegate void ChangedEventHandler(object sender, EventArgs e);

    public class ListWithChangedEvent : ArrayList
    {
        // イベントの宣言
        // event キーワードに注意。
        // クラスの外からはフィールドのように見える。ただし、アクセスには制限があり、実行で
        // きるのは、以下の処理だけ。
        //  ・新しいデリゲートの結合
        //   ・(結合されている場合は)デリゲートの削除
        // これらの処理には、+= および -= 演算子を使用する。

        public event ChangedEventHandler Changed;

        // イベントの起動
        // デリゲートをイベントにフックしているクライアントがない場合、フィールドは null に
        // なる。それ以外の場合は、イベント起動時に呼び出すデリゲートへの参照となる。このた
        // め、一般にイベントが起動される場合はまずこのフィールドが null かどうかを調べ、そ
        // の後イベントを呼び出す。

        // イベントは、イベントを宣言したクラスの中からしか起動できない。イベントを起動する
        // protected メソッドを作成しておき、このメソッドを呼び出すことによって、派生クラスが
        // イベントを起動できる。さらに柔軟性を持たせるために、起動メソッドを virtual とし
        // て宣言することも多くある。これにより、派生クラスは、そのメソッドをオーバーライド
        // できる。
        protected virtual void OnChanged(EventArgs e)
        {
            if (Changed != null)
                Changed(this, e);
        }

        // リストへの追加、リストのクリア、リストの要素への代入の際にイベントを起動

        public override int Add(object value)
        {
            int i = base.Add(value);
            OnChanged(EventArgs.Empty);
            return i;
        }

        public override void Clear()
        {
            base.Clear();
            OnChanged(EventArgs.Empty);
        }

        public override object this[int index]
        {
            set
            {
                base[index] = value;
                OnChanged(EventArgs.Empty);
            }
        }
    }
}

[ 親 91453 / □ Tree ] 返信 編集キー/

▲[ 91456 ] / 返信無し
■91458 / 2階層)  Re[2]: onShown など on〜の使い方
□投稿者/ エベェ (2回)-(2019/06/29(Sat) 14:04:26)

WebSurfer 様

ご返信ありがとうございます
Docsにて記載の内容は見させていただいてましたが
意味がはっきりしませんでしたが
具体的なコードを見せていただき使い方がよくわかりました


魔界の仮面弁士 様

とあるイベントを起こしたくないとか
とあるイベントの前に何か作業をしたいとか
そういったときの細かい制御ができるということですね

わかりやすいご説明ありがとうございました


これにて解決済をつけさせていただきます
早速のご教授本当にありがとうございました
解決済み
[ 親 91453 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -