- PR -

ASP.NETでカスタムコントロールにイベントを追加するには?

投稿者投稿内容
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2003-09-09 16:21
VB.NETでWebカスタムコントロールを作成しているのですが、イベントのキャプチャ方法がわからず困っています。

コントロールの内容は、さまざまな値を表示しているテーブルと、イメージボタンが1つあるだけです。
見よう見真似で以下のように記述しています。

<DefaultProperty("Text"), ToolboxData("<{0}:CustonControl1 runat=server></{0}:CustonControl1>")> Public Class CustonControl1
  Inherits System.Web.UI.WebControls.WebControl
  Implements IPostBackEventHandler

  Public Event Click As EventHandler

  Protected Overridable Sub OnClick(ByVal e As EventArgs)
    RaiseEvent Click(Me, e)
  End Sub

  Public Sub RaisePostBackEvent(ByVal eventArgument As String) _
  Implements IPostBackEventHandler.RaisePostBackEvent
    OnClick(New EventArgs())
  End Sub

  Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)

    Dim strHTML As String
    
        :
    strHTML &= " <INPUT type='image' id='btnSearch' src='../images/search_small.gif' name='" & Me.UniqueID & "'>"
        :
    output.Write(strHTML)
  End Sub

どなたかご指導いただけないでしょうか?
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2003-09-09 18:24
なかむらさん、こんばんは。

コード:
    strHTML &= " <INPUT type='image' id='btnSearch' src='../images/search_small.gif' name='" & Me.UniqueID & "'>"


手っ取り早く、この部分を
コード:
strHTML &= "<A href=""javascript:" & Page.GetPostBackEventReference(Me) & """><img src=""../images/search_small.gif"" border=""0"" /></a>"


こんな風に書き換えてみるというのはどうでしょう。
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2003-09-10 09:11
きくちゃんさん、レスありがとうございます。

引用:

コード:
    strHTML &= " <INPUT type='image' id='btnSearch' src='../images/search_small.gif' name='" & Me.UniqueID & "'>"


手っ取り早く、この部分を
コード:
strHTML &= "<A href=""javascript:" & Page.GetPostBackEventReference(Me) & """><img src=""../images/search_small.gif"" border=""0"" /></a>"


こんな風に書き換えてみるというのはどうでしょう。



試してみましたがやはりダメですね。
デバッグをしてみるとポストバック自体は正常に発生しているようなのですが、
Clickイベントを拾えていないようです…。
うーん、困った…
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2003-09-10 12:22
なかむらさん、こんにちは。

引用:

デバッグをしてみるとポストバック自体は正常に発生しているようなのですが、
Clickイベントを拾えていないようです…。


提示されたコードを貼り付けて、前回提案した部分のみを書き換えて実行したところ、ちゃんとClickイベントが発生しました。
問題は、他にあるんじゃないでしょうか...。

フォーム側の記述とか、どうなってます?
FOX
ベテラン
会議室デビュー日: 2002/04/08
投稿数: 63
お住まい・勤務地: いなか
投稿日時: 2003-09-10 12:57
こんにちは。

以前私も同じようなことをしたときのサンプルがあります。
#ただしC#です。

このカスタムコントロールはボタンががクリックされたらイベントを挙げるだけです。
多分ASPボタンの機能縮小版とでもいうようなものです。

#スクリプトの部分はフォームのIに似合わせて変更する必要があります。

コード:

using System;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace myWebControls {
/// <summary>
/// TestControl
/// </summary>
public class TestControl : WebControl , IPostBackEventHandler {
/// <summary>
/// Clickイベント
/// </summary>
public event EventHandler Click;

/// <summary>
/// コンストラクタ
/// </summary>
public TestControl() {
this.PreRender += new EventHandler(this.PreRenderHandler);
}

/// <summary>
/// 描画前イベント
/// </summary>
protected void PreRenderHandler(object sender, EventArgs args) {
Page.RegisterHiddenField("__EVENTTARGET","");
Page.RegisterHiddenField("__EVENTARGUMENT","");
// スクリプト登録用
StringBuilder buf = new StringBuilder("<script language=\"JScript\">");
buf.Append("function test(id,arg) {");
//buf.Append("alert(id + \":\" + arg);");
buf.Append("Form1.__EVENTTARGET.value = id;");
buf.Append("Form1.__EVENTARGUMENT.value = arg;");
buf.Append("Form1.submit();");
buf.Append("}</script>");
if(!Page.IsClientScriptBlockRegistered("test")) {
Page.RegisterClientScriptBlock("test",buf.ToString());
}
}

protected override void Render(HtmlTextWriter render) {
// コントロールの描画
render.WriteLine("<input value=\"test\" type=\"button\" onclick=\"test('{0}','onclick')\" style=\"{1}\" />",UniqueID,Attributes["style"]);
}

/// <summary>
/// Clickイベントを発生させる
/// </summary>
protected void OnClick() {
//イベントが登録されていたら実行
if(null != Click) {
Click(this,new EventArgs());
}
}

/// <summary>
/// ユーザが定義したコールバックイベント時に対応するイベントを起動する
/// </summary>
/// <param name="eventArgument">イベント名</param>
public void RaisePostBackEvent(string eventArgument) {
OnClick();
}
}
}




[ メッセージ編集済み 編集者: FOX 編集日時 2003-09-10 12:59 ]
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2003-09-10 12:59
きくちゃんさん、レスありがとうございます。

引用:

提示されたコードを貼り付けて、前回提案した部分のみを書き換えて実行したところ、ちゃんとClickイベントが発生しました。
問題は、他にあるんじゃないでしょうか...。

フォーム側の記述とか、どうなってます?



ためしに自分が提示したコードを新規に貼り付けて、きくちゃんさんのコードに書き換えて試してみたら…ちゃんとClickイベント発生しました。

あれぇ?と思って以前のコントロールでも再度試してみると…ちゃんとClickイベント発生しました。
原因を調査してみると、昨日ここへ書き込みをしてからきくちゃんさんのアドバイスを頂くまでの間に追加した以下のコードが原因でした。
コード:
    Public Interface IPostBackEventHandler
        Sub RaisePostBackEvent(ByVal eventArgument As String)
    End Interface


どこかのページを見て追加したんだと思いますが、これをコメントアウトしたらできました。
これって何なのでしょうか?

あと、カスタムコントロール作成に非常に役立つページ、または書籍をご存知ありませんか?
どうも資料が少なくて…。
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2003-09-10 18:15
なかむらさん、こんばんは。

引用:

コード:
    Public Interface IPostBackEventHandler
        Sub RaisePostBackEvent(ByVal eventArgument As String)
    End Interface


どこかのページを見て追加したんだと思いますが、これをコメントアウトしたらできました。
これって何なのでしょうか?


えーと、IPostBackEventHandler インターフェイス(と同じ名前のインターフェイス)を自前で定義しちゃったんですね。

で、カスタムコントロールの中の記述で、
Implements System.Web.UI.IPostBackEventHandler
ではなく、
Implements IPostBackEventHandler
としているので、自前のインターフェイスの方をインプリメントしちゃってるという...。
なので、ポストバックの処理機能を持ったコントロールであるとは、みなされなかったんでしょう。

引用:

あと、カスタムコントロール作成に非常に役立つページ、または書籍をご存知ありませんか?
どうも資料が少なくて…。


いやー、私もそういうのがあれば教えて欲しいくらいで、MSDNライブラリを解読するしかありませんでした。実行時の動作はまだ良いんですが、デザイン時の動作(特にカスタムエディタとか)は、かなり悩みました。

あと、vs.netも2002の時は、オブジェクトブラウザで Attribute の定義が丸見えだったんで参考になりましたが、2003になって、その辺が見えなくなっちゃったんですよね...。
なかむら
ベテラン
会議室デビュー日: 2001/10/22
投稿数: 67
投稿日時: 2003-09-11 09:46
FOXさん、レスありがとうございます。

まだカスタムコントロールのイベント定義について理解できていませんので、
FOXさんのサンプルを見て一つずつ勉強していきたいと思います。

非常に参考になるサンプルを提示してくださいましてありがとうございました。

スキルアップ/キャリアアップ(JOB@IT)