|
魔界の仮面弁士 さん、ありがとうございます。
> 継承元の Arrange メソッドを、継承元自身の Control_Load から呼び出すという点は分かりましたが、 > その前の、Lb(配列型のフィールド変数)を、Arrange 関数にまとめる…という部分が良く分かりません。 > どのようなコードに変更されたのでしょうか?
以下のように、Lbの実体を宣言し、配置をし直すところをまとめて1つの関数にしました。 これを、Control_Loadから呼び出しています。 #継承元のControl_Loadからも継承先のControl_Loadからもこれを呼び出してLbの実態を作成しています。 protected void Arrange() { int nMidLb = 0; int nWidth = 0; //隣の間の隙間を含むサイズ int nMid = 0; int nLeft = 0;
this.SuspendLayout();
//コントロール配列の作成 Lb = new System.Windows.Forms.Label[m_Max];
//コントロールのインスタンス作成し、プロパティを設定する for (int i = 0; i < Lb.Length; i++) { //インスタンス作成 Lb[i] = new System.Windows.Forms.Label(); //プロパティ設定 Lb[i].Name = "Lb" + i.ToString(); Lb[i].Size = new Size(29, 36); Lb[i].Location = new Point(i * 30, 10); Lb[i].Visible = true; Lb[i].BackColor = Color.Gray; //イベントハンドラに関連付け Lb[i].Click += new EventHandler(this.LB_Click); } //フォームにコントロールを追加 Picture1.Controls.AddRange(this.Lb);
nMid = this.Width / 2 + 25; //真中のINDEX取得 if (m_Max % 4 != 0) { nMidLb = (m_Max + 4 - (m_Max % 4)) / 2; } else { nMidLb = m_Max / 2; }
nLeft = nMid; //画面左部のイメージ整列 for (int i = nMidLb; i <= m_Max - 1; i++) { if (i % 4 == 0) { nLeft = (int)(nLeft - nWidth * 1.5); } else { nLeft = nLeft - nWidth; } Lb[i].SetBounds(nLeft, Lb[i].Top, nWidth - 3, Lb[i].Height); } if ((nMidLb % 4) == 0) { nLeft = (int)(nMid - nWidth * 1.5); } else { nLeft = nMid - nWidth; } //画面右部のイメージ整列 for (int i = nMidLb - 1; i >= 0; i += -1) { if ((i + 1) % 4 == 0) { nLeft = (int)(nLeft + nWidth * 1.5); } else { nLeft = nLeft + nWidth; } Lb[i].SetBounds(nLeft, Lb[i].Top, nWidth - 3, Lb[i].Height); } this.ResumeLayout(true); }
>>継承元では、 >> public event EventHandler LbClicked; >> protected virtual void OnLbClicked(object sender, EventArgs e) > イベントを実装する場合、対応する OnEventName メソッドには sender を渡しません。 > sender はフォーム自身なので、あえて引数に渡す必要が無いためです。 > > すなわち、EventArgsまたはその継承クラスだけを受け取るように実装します。 > フォームの OnLoad や OnFormClosing メソッドも、そうなっていますよね。 > > なお、イベントの利用側に、どのラベルをクリックしたかと言う情報を伝える必要が > ある場合には、それを EventArgs を継承させたクラスを使って渡すようにします。 > (TreeView の AfterSelect イベントなどがそうであるように) > > >>継承先では、 >> public new event EventHandler LbClicked; > 継承先で、イベントをシャドウイングしているようですが、それは何故ですか? > > 普段、Form を継承して Form1 クラスを作る際に、継承元の Load イベントを処理するためには > 『public new event EventHandler Load;』と書いたりはしないかと思います。通常は、 > 「Load += 〜 でイベントを割り当てる」か、「OnLoad をオーバーライドする」ぐらいでしょう。 > > 今回も同様で、特に理由が無ければ、同名イベントを再実装する必要は無いと思いますよ。
継承先にもLB_Clickがあるため、継承先は継承先で宣言が必要かと思っていました。 また、継承元、継承先にのLB_Clickの中で関数の最後に if (LbClicked != null) { OnLbClicked(this, e); } の記述を入れているため、継承先にも宣言してないとエラーになってしまうこともあり、記述していました。
>> protected override void OnLbClicked(object sender, EventArgs e) > 必ずしもオーバーライドさせる必要は無いかと思いますが、オーバーライドさせるならば、 > 継承元のベースメソッドを呼びだすコードも含めておくべきかと。
申し訳ないのですが、ここの意味が理解できませんでした。 継承先の宣言でnew eventで新しく割り付け直したつもりだったのですが、違うのでしょうか?
>>イベントは飛んできませんんでした。 > そもそも、継承元フォームで LbClicked イベントを発生させていますか? > > 今回の実装だと、継承元側は Label の Click イベントを受け取ったときに、 > OnLbClicked メソッドを呼び出す必要がありますよね。
Lbの実体を宣言する時に、イベントハンドラをLB_Clickにくくりつけているのですが、 LB_Click関数の最後に if (LbClicked != null) { OnLbClicked(this, e); } を入れています。
|