0

:

これは私の最初の投稿です。私の誤解を許してください :D 私が直面している問題は次のとおりです。データ リスト内の「ImageButton」からイベントをキャッチしようとしていますが、いくつかの問題が発生しています。

何らかのアクションを実行するために起動されたボタンをキャッチする必要があります (そのため、それを特定する必要があります)。ボタンは、「DataList」に含まれるユーザー コントロール内にあり、ユーザー コントロール内に配置され、ページから読み込まれます (マスター ページもあります)。ここでネストされた順序を確認できます: Page->User-Control->DataList->User Control->ImageButton

Web アプリケーションは Web フォーム MVP パターンを使用して構築されているため、ページ (コントロールではない) にはすべてのロジックを管理し、データを送信して Web フォームをバインドし、必要なコントロールをロードするプレゼンターがあります。

メンバー.aspx

.......
<%@ Register Src="~/Controls/DataControl.ascx" TagName="DataBox" TagPrefix="dtC" %>
.......
<dtC:DataBox ID="DataBoxControl" runat="server" />

メンバー.aspx.cs

    protected void Page_Load(object sender, EventArgs e)
    {
        _presenter = IoCFactory.Instance.CurrentContainer.Resolve<IMembersPresenter>();

        _presenter.Init(this, IsPostBack);

    }
......
    public void ShowFriendPanel(IList<ContactInfo> friendList)
    {
        DataBoxControl.FriendsList = friendList.ToList();
    }

プレゼンターは次のようになります。

    public override void Init(IMemberView view, bool isPostBack)
    {
        base.Init(view,isPostBack);//authentication and basic stuff


        IList<ContactInfo> friendContactList = _userAccountDao.GetFriendsOfUser(CurrentUser.Id, 0, int.MaxValue);


        if ((friendContactList.Count > 0))
        {
            ShowFriendsBox(friendContactList);

        }

また、コントロール DataBoxControl には、別のユーザー コントロールを含むデータ リストが含まれています。

  <asp:DataList ID="dataDL" runat="server" OnItemDataBound="dataDL_ItemDataBound" OnItemCommand="dataDL_ItemCommand"   >
        <ItemTemplate>
             <ci1:ContactImage runat="server" ID="ContactImageControl" Height="59px" Width="59"  Show="All" />
        </ItemTemplate>
  </asp:DataList>

最終的なユーザー コントロール (ContactImage.ascx) には、Web コントロール 'ImageButton' が含まれます。

 ......
 <asp:ImageButton ID="deleteButton" ImageUrl="/images/remove_contact_icon.png" runat="server"  />
  .......

アクションを実行する ID は、「ContactImage」コントロールでイメージ ボタン「CommandName」に割り当てられます。これは、ボタンがクリックされたときに取得する必要がある値です。実際、ContactImage ユーザー コントロールは内部で何も実行せず、発生したイベントをデータ リストの OnItemCommand に依存していますが、次の 2 つの問題があります。

  1. Page_Load の前にデータ リストをバインドできないため、「IsPostBack」が false のときにデータ バインドが行われていることを確認する必要があります。その場合、ContactImage がそのプロパティをフルフィルしようとして失敗するため、発生したイベントは発生しません (List がバインドされていないため、DataList Item は空です)。
  2. データ リスト バインディングが Page_Init (ユーザー コントロール内) に移動されると、イベントが発生しますが、OnItemCommand は何も受け取りません (データ リストをバインドするリストも空です)。

シンプルなWebサイトを構築し、それが機能し、イベントがItemCommandに到達するため、使用しているパターンが何らかの形で責任を負っているのだろうか

シンプルな Web サイト (ここでは動作しますが、MVP パターンは使用されていません) Event.aspx

 <h2>
    Events
</h2>
<p>
    Events into Data List
</p>
<asp:DataList ID="DataListWihtEvents" RepeatDirection="Horizontal" RepeatColumns="4" OnItemCommand="DataList_ItemCommand" runat="server">
    <ItemTemplate>
        <tnc:TopControl ID="TopControlNested" runat="server" Number="<%# (Container.DataItem) %>" />
    </ItemTemplate>
    <SeparatorTemplate>&nbsp;</SeparatorTemplate>
</asp:DataList>
<br />
<asp:Label ID="ShowButtonFiredUpTitle" runat="server" Text="Here goes the button that was fired up: " />
<asp:Label ID="ShowButtonFiredUp" runat="server" Font-Bold="True" />

Event.aspx.cs

public partial class Events : System.Web.UI.Page
{
    protected List<int> Numbers = new List<int>();

    protected void Page_Init(object sender, EventArgs e)
    {
        for (int i = 1; i < 5; i++)
        {
            Numbers.Add(i);
        }

        DataListWihtEvents.DataSource = Numbers;
        DataListWihtEvents.DataBind();
    }

    protected void DataList_ItemCommand(object source, DataListCommandEventArgs e)
    {
        if (e.CommandSource.GetType() == typeof(Button))
        {
            var b = (Button) e.CommandSource;
            ShowButtonFiredUp.Text = b.CommandName;
        }

    }

TopNestedControl.ascx

<%@ Register Src="~/Controls/BottomNestedControl.ascx" TagName="BottomControl" TagPrefix="bnc" %>

TopNestedControl.ascx.cs

public partial class TopNestedControl : System.Web.UI.UserControl
{
    public int Number { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        BottomNestedControl.Number2 = Number;
    }
}

BottomNestedControl.ascx

<asp:Button ID="ShowNumberButton" runat="server" Text="Button" CommandName="button fired up!" />

BottomNestedControl.ascx.cs

public partial class BottomNestedControl : System.Web.UI.UserControl
{
    public int Number2 { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        ShowNumberButton.Text = "Button " + Number2;
        ShowNumberButton.CommandName = "#" + Number2;
    }
}

他のページでは、デリゲートを使用してイベントを処理していますが、「DataList」は使用されておらず、イベントは問題なくキャッチされています。とにかく誰かがこの混乱を解くのを手伝ってくれたらとてもうれしいです.

前もって感謝します、

ハビエル

4

2 に答える 2

0

ご回答ありがとうございます。できる限り詳しく説明させてください

ページをレンダリングし、IE または Chrome または Firebugs (Firefox の場合) を使用して、f12 を押します。問題のボタンの 1 つを選択し、CommandName 属性が正しく設定されているかどうかを確認します。上記のコードから、そのプロパティは設定されていないため、コードビハインドで設定したと想定しました。

はい、'CommandName' は分離コードに設定されています。オブジェクトを 'ContactImage' ユーザー コントロールに渡し、それにはプロパティ (ID) が含まれています。デバッグ中に確認し、正しい値を取得しました。

ボタン (ポストバックのソース) にアクセスできる場合は、他の属性をボタンにバインドして、その情報を使用するだけです。

はい、私は実際にそのボタンにアクセスでき、必要なデータがあります。コントロール内にロジックを追加することもできますが、ソフトウェア設計 (Web フォーム MVP パターン) を維持するために、プレゼンターにイベントを発生させる必要があります。私が関与しているミッション:)

CommandName と OnItemCommand が適切に設定されていてもイベントがキャッチされない場合は、いつでもカスタム イベントをボタンにアタッチして発生させることができます。

イベント委任を使用して最初に試したのですが、うまくいかないようでした。何よりも前にコードを再確認する必要があるかもしれませんが、Data List は内部で起動されたすべてのイベントをキャッチできることを読んだので、コードの量を減らし、ユーザー コントロールからロジックを抽出する最短の方法に進みます。

ID="dataDL" オブジェクトで、カスタム コントロールを削除し、単純な asp:button を静的なコマンド名で配置してから、デバッグ モードで実行し、dataDL_ItemCommand がトリガーされるかどうかを確認します。イベントが発生しないのは奇妙だと思います。

ああ、私はそれをしたいです。私が構築したサンプル Web サイト (投稿の最新コード) ではすべて正常に動作しますが、実際のアプリでは、他のコントロールやページで使用されているため、「ContactImage」コントロールをそのまま維持する必要があり、それがユーザー コントロールである理由です。 .

現在、あなたの投稿からは、どのタイプの問題が発生しているかは明確ではありません。解決策を提案しやすいように制限する必要があります。

申し訳ありません。それは私のせいです。主な問題は次のとおりです。イメージ ボタンがクリックされたときに (親コントロールのデータ リスト内にあるコントロール内で) イベントを取得できず、プレゼンターに引数を渡すことができません。

私が見た問題は、Data List が Page Load 内にバインドされている場合、ボタンをクリックするとエラーが発生することです。「PostBack」が false であることを確認せずに (まだ画像を投稿できません。申し訳ありません)

最初にこれをチェックする場合:

DataBoxControl.ascx.cs

........

public WhatEverType WhatEverData
{
    get;
    set;
}
protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataListWihtEvents.DataSource = WhatEverData;
        DataListWihtEvents.DataBind();
    }


}

PostBack 中にデータ リストがバインドされず、アプリケーションが内部のコントロールを「描画」しようとして失敗するため、イベントがキャッチされるかどうかはわかりません。データ バインディングを他のページ ライフ サイクル (Init、Binding、PreLoad など) に移動しようとしましたが、奇妙なことに、List にはまだデータがありません。Presenter はメインの Page Init で呼び出されますが、Page Load (そして Control:Init が完了) までデータはコントロールに渡されません。

データ バインディングを 2 回 (コントロールの Page Init と Load の両方) 追加し、PostBack 中にトリックを作成しましたが、コントロールがデータなしで描画されている間 (エラー出力はありません)、イベントは 'ItemCommand' に到達せず、失われたようです。

これらすべては、ページのライフ サイクル (コントロールではより複雑) の問題と、PostBack の処理中に起動されるイベントのように思えます。

于 2011-07-13T23:14:00.533 に答える
0

レイヤーが多すぎると、ページのライフサイクルが非常に重要な役割を果たします。どのサイクルでどのアクションを実行する必要があるかについて詳しく説明する代わりに (Google の方が優れています)、代わりにいくつかのヒントとコツを説明します。

ページをレンダリングし、IE または Chrome または Firebugs (Firefox の場合) を使用して、f12 を押します。問題のボタンの 1 つを選択し、CommandName 属性が正しく設定されているかどうかを確認します。上記のコードから、そのプロパティは設定されていないため、コードビハインドで設定したと想定しました。

  • ボタン (ポストバックのソース) にアクセスできる場合は、他の属性をボタンにバインドして、その情報を使用するだけです。

  • CommandName と OnItemCommand が適切に設定されていてもイベントがキャッチされない場合は、いつでもカスタム イベントをボタンにアタッチして発生させることができます。

  • ID="dataDL" オブジェクトで、カスタム コントロールを削除し、単純な asp:button を静的なコマンド名で配置してから、デバッグ モードで実行し、dataDL_ItemCommand がトリガーされるかどうかを確認します。イベントが発生しないのは奇妙だと思います。

現在、あなたの投稿からは、どのタイプの問題が発生しているかは明確ではありません。解決策を提案しやすいように制限する必要があります。

于 2011-07-13T18:32:28.393 に答える