Событие запуска от кнопки изображения в пользовательском элементе управления в списке данных - PullRequest
0 голосов
/ 13 июля 2011

:

Это мой первый пост, поэтому я прошу вас простить мои ошибки: D Проблема, с которой я сталкиваюсь, заключается в следующем: я пытаюсь поймать событие из некоторого 'ImageButton' внутриСписок данных, но у меня возникли некоторые проблемы.

Мне нужно перехватить любую кнопку, которая срабатывает, чтобы выполнить какое-либо действие (поэтому мне нужно определить его).Кнопка находится внутри пользовательского элемента управления, который содержится в «DataList», который находится внутри пользовательского элемента управления, который загружается со страницы (которая также имеет мастер-страницу).Вы можете увидеть вложенный порядок здесь: Page-> User-Control-> DataList-> User Control-> ImageButton

Я должен сказать, что веб-приложение построено с использованием шаблона MVP веб-форм, поэтому страницы (не элементы управления) имеютPresenter, который управляет всей логикой и отправляет данные для связывания веб-форм, загружая необходимые элементы управления.

Members.aspx

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

Members.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();
    }

Presenter выглядит следующим образом:

    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"  />
  .......

Идентификатор действия назначен в элементе управления ContactImage для кнопки изображения «CommandName», и это значение мне нужно получить при нажатии кнопки.На самом деле, пользовательский элемент управления ContactImage ничего не делает внутри, и я полагаюсь на запущенное событие на OnItemCommand в списке данных, но у меня есть две проблемы:

  1. Я не могу связать список данных до Page_Load, поэтому я имеюпроверять привязку данных, когда IsPostBack имеет значение false;в этом случае сработавшее событие не происходит, потому что не удается ContactImage при попытке заполнить его свойства (Элемент DataList пуст, потому что List не привязан).
  2. Если привязка Списка данных перемещена в Page_Init (вКонтроль пользователя) событие запускается, но OnItemCommand вообще ничего не получает (и Список для привязки Списка данных также пуст).

Интересно, отвечает ли используемый мной шаблонкаким-то образом, потому что я создал простой веб-сайт, и он работает, и событие достигает ItemCommand

Simple Website (здесь он работает, но шаблон 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, и событие перехватывается без проблем.Я был бы очень рад, если бы кто-нибудь помог мне разобраться в этом беспорядке.

Заранее спасибо,

Хавьер

Ответы [ 2 ]

0 голосов
/ 14 июля 2011

Спасибо за ваш ответ.Позвольте мне объяснить как можно лучше

Дайте странице отрисоваться, используйте IE или Chrome или Firebugs (для Firefox) и нажмите f12.Выберите одну из рассматриваемых кнопок и посмотрите, правильно ли установлен атрибут CommandName.Исходя из вашего кода выше, это свойство никогда не устанавливалось, поэтому я предположил, что вы сделали это для кода позади.

Да, 'CommandName' установлено в коде позади.Я передаю объект в пользовательский элемент управления «ContactImage», который содержит свойство (идентификатор).Я проверил это во время отладки и принял правильное значение.

Если у вас есть доступ к кнопке (источник сообщения назад), вы можете просто привязать другие атрибуты к кнопке и использовать эту информацию.

Да, у меня действительно есть доступ к этой кнопке, и она имеет необходимые данные, даже я мог бы добавить некоторую логику в элемент управления, но, чтобы сохранить дизайн программного обеспечения (шаблон веб-формы MVP), мне нужно повыситьсобытие в Presenter, и это миссия, в которой я участвую:)

Если CommandName и OnItemCommand настроены правильно, но событие все еще не перехватывается, вы всегда можете прикрепитьнастраиваемое событие для кнопки и вызовите его.

Сначала я попробовал использовать делегирование событий, но оно, похоже, не сработало.Может быть, мне нужно перепроверить мой код, прежде чем что-то, но я прочитал, что Data List способен перехватывать все запущенные события внутри него, поэтому я стремлюсь к кратчайшему пути уменьшения объема кода и извлечения любой логики из пользовательских элементов управления.

В вашем объекте ID = "dataDL" удалите пользовательский элемент управления и вставьте простую кнопку asp: со статическим именем команды, затем запустите его в режиме отладки и посмотрите, запускает ли он даже dataDL_ItemCommand.Я нахожу странным, что событие не запускается.

О, я бы хотел это сделать.На созданном мной примере веб-сайта (последний код в моем сообщении) все работает правильно, но в реальном приложении мне нужно сохранить элемент управления «ContactImage» таким, какой он есть, потому что он используется другими элементами управления и страницами, и поэтому он является пользовательским элементом управления..

Прямо сейчас, из вашего поста не ясно, какие у вас проблемы.Вы должны ограничить его, чтобы было легче предложить решение.

Жаль это слышать;это моя вина.Основная проблема: я не могу получить событие при нажатии кнопки изображения (в элементе управления, который находится внутри списка данных в родительском элементе управления) и передать аргумент докладчику.

Проблема, с которой я столкнулся, заключается в том, что я получаю сообщение об ошибке при нажатии кнопки, если список данных связан с загрузкой страницы, без проверки, что «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 вызывается на главной странице Init, но данные не передаются в управление до тех пор, пока не будет загружена страница (и тогда Control: Init не выполнит).

Я только что сделал трюк, добавив привязку данных дважды (как для Init и Load страницы элемента управления), так и во время PostBack, в то время как элемент управления отображался без данных (поэтому без вывода ошибок), событие никогда не попадает в ItemCommand, и онокажется потерянным.

Все эти вещи, как мне кажется, проблема с жизненным циклом страницы (более сложная с элементами управления) и событиями, которые запускаются во время обработки PostBack.

0 голосов
/ 13 июля 2011

Когда существует слишком много слоев, жизненный цикл страницы играет действительно важную роль.Вместо того, чтобы вдаваться в подробности о том, какие действия должны выполняться в каком цикле (Google делает лучшую работу), я просто собираюсь изложить некоторые советы и рекомендации вместо этого.

Позвольте странице отображаться, используйте IE илиChrome или Firebugs (для Firefox) и нажмите f12.Выберите одну из рассматриваемых кнопок и посмотрите, правильно ли установлен атрибут CommandName.Исходя из вашего кода выше, это свойство никогда не устанавливалось, поэтому я предположил, что вы сделали это с кодом позади.

  • Если у вас есть доступ к кнопке (источник сообщения назад), выможно просто привязать другие атрибуты к кнопке и использовать эту информацию.

  • Если CommandName и OnItemCommand настроены правильно, но событие по-прежнему не перехватывается, вы всегда можете прикрепить пользовательскийсобытие для кнопки и поднять его.

  • В вашем объекте ID = "dataDL" удалите пользовательский элемент управления и вставьте простую кнопку asp: со статическим именем команды, затем запустите еев режиме отладки и посмотреть, если он даже запускает dataDL_ItemCommand.Я нахожу странным, что событие не запускается.

Прямо сейчас, из вашего поста неясно, какие у вас проблемы.Вы должны ограничить его, чтобы было легче предложить решение.

...