1

クライアント機能を備えたASP.NETサーバーコントロールについて質問があります。クライアント側のイベント処理を改善したい:子クライアントコントロールがイベントを発生させたときに、親クライアントコントロールに直接通知されるようにしたい。

MyWindowとMyTextBoxの2つのサーバーコントロールがあると仮定します。どちらも「Sys.UI.Control」タイプのクライアント側オブジェクトです。

MyTextBoxはMyWindowの子です。

public class MyWindow : Control, IScriptControl
{
   private MyTextBox _mtb;
   //....
   protected override void CreateChildControls()
   {
       _mtb = new MyTextBox();
       _mtb.ID = "MTB";
       _mtb.OnClientTextChanged = "OnClientTextChanged";
       Controls.Add(_mtb);
   }

   //...
   public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
  {
     ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Test.MyWindow", ClientID);
     descriptor.AddComponent("myTextBox", _mtb.ClientID);
     yield return descriptor;
  }

クライアント側:

  function OnClientTextChanged(sender, args) {
      alert('test')
  }

これで、テキストボックスのテキストが変更されるたびに、client-eventが発生し、関数「OnClientTextChanged」が呼び出されます。

私が欲しいのは、クライアントオブジェクトに「MyWindow」を通知することです。私はこのようにそれを行うことができます:

  function OnClientTextChanged(sender, args) {
      $find("MyWindow").textBoxChangedItsText();
  }

しかし、このグローバルjavascript関数を使用せずに、MyWindowのクライアントオブジェクトに直接通知するにはどうすればよいですか?私がテストしたのは

_mtb.OnClientTextChanged = string.Format("($find('{0}')).textBoxChangedItsText", ClientID);

しかし、クライアントオブジェクト内の「textBoxChangedItsText」関数はオブジェクト自体にアクセスできません。「this」は関数自体ですが、「$ find( "MyWindow")」を使用して検索するオブジェクトではありません。

クライアント側で有効なAJAXサーバー側の制御に関する知識を持っている人には、この質問が明確になることを願っています。

ありがとう!

編集:クライアント側でこのイベントハンドラーを使用すると、次のように機能します。

サーバ側:

 _mtb.OnClientTextChanged = string.Format(" ($find('{0}')).textBoxChangedItsTextDelegate", ClientID);

クライアント側:

Test.MyWindow = function (element) {
   Test.MyWindow.initializeBase(this, [element]);
   this.textBoxChangedItsTextDelegate= Function.createDelegate(this, function (sender, e) {
      this.textBoxChangedItsText();
   });
};

Test.MyWindow.prototype = {
   initialize: function () {
      Test.MyWindow.callBaseMethod(this, 'initialize');
   },
   textBoxChangedItsText: function () {
      alert(this.get_id());
   },
   dispose: function () {
      Test.MyWindow.callBaseMethod(this, 'dispose');
   }
};

私がまだ気に入らないのは、イベントハンドラーの$ findを使用してイベントサーバー側にアタッチすることです:_mtb.OnClientTextChanged = string.Format( "($ find('{0}'))。textBoxChangedItsTextDelegate"、ClientID );

4

1 に答える 1

1

基本的に ASP.NET クライアント側コントロールで行われるように、イベントを定義する必要があると思います。そのため、MyTextBox クライアント側オブジェクト プロトタイプに以下を追加する必要があります。

add_textChanged: function(handler) {
    this.get_events().addHandler('shown', handler);
}
remove_TextChanged: function (handler) {
    this.get_events().removeHandler('textChanged', handler);
}
raise_textChanged: function (eventArgs) {
    var handler = this.get_events().getHandler('textChanged');
    if (handler) {
        handler(this, eventArgs);
    }
}

これにより、クライアント コード (親コントロールまたはページ) がサブスクライブして必要なアクションを実行できるクライアント側イベントが定義されます。MyTextBox でこのイベントを発生させるには、次のようなコードを使用できます。

this.raise_textChanged(Sys.EventArgs.Empty);

MyWindow クライアント側オブジェクトでこのイベントを使用するには、コードを次のように変更する必要があります。

Test.MyWindow = function (element) {
   Test.MyWindow.initializeBase(this, [element]);

   this._myTextBoxID = null;
   this._onTextChanged$delegate = Function.createDelegate(this, this._onTextChanged);
};

Test.MyWindow.prototype = {
   initialize: function () {
      Test.MyWindow.callBaseMethod(this, 'initialize');

      $find(this._myTextBoxID).add_textChanged(this._onTextChanged$delegate);
   },

   _onTextChanged: function(sender, eventArgs) {
        // Perform required actions.
        // this - will be instance of the this client side object.
   }

   dispose: function () {
        $find(this._myTextBoxID).remove_textChanged(this._onTextChanged$delegate);

      Test.MyWindow.callBaseMethod(this, 'dispose');
   }
};

注: 提供された例では、子 MyTextBox コントロールのクライアント ID に等しい this._myTextBox を使用しました。descriptor.AddComponent("myTextBox", _mtb.ClientID); を使用して初期化するため、$find を実行せずにプロパティ "myTextBox" を使用できます。

于 2012-11-21T07:44:09.583 に答える