Динамически добавленное событие ImageButton Command не запускается до второго щелчка - PullRequest
2 голосов
/ 23 февраля 2012

У меня есть страница, на которой я динамически добавляю ImageButtons.Сначала я установил OnClientClick кнопок, чтобы они просто отображали всплывающее окно увеличенного изображения и возвращали значение false для отсутствия обратной передачи.

У меня есть кнопка на странице для установки «основного изображения», поэтому при нажатии этой кнопки я устанавливаю свойство с именем _IsSettingPrimaryPhotoMode = true, вызываю функцию для воссоздания ImageButtons и при создании ImageButtons, если этосвойство равно true вместо добавления OnClientClick, я подключаю CommandEventHandler, чтобы я мог сказать, какая кнопка была нажата, читая CommandArgument.

Проблема в том, что обработчик событий не срабатываетпервый клик по изображению, но только по второму клику и после.Я также переместил код с Page_Load на OnInit и загружаю кнопки ImageButtons при каждой обратной передаче.

Я сохраняю _IsSettingPrimaryPhotoMode в Session.

private bool _IsSettingPrimaryPhotoMode {
    get {
        bool result = false;

        if(Session[ConstantsWeb.Session.IS_DELETE_IMAGE_MODE] != null) {
            result = Convert.ToBoolean(Session[ConstantsWeb.Session.IS_SETTING_PRIMARY_IMAGE_MODE]);
        }

        return result;
    }
    set {
        Session[ConstantsWeb.Session.IS_SETTING_PRIMARY_IMAGE_MODE] = value;
    }
}

Страница OnInit

protected override void OnInit(EventArgs e) {
    base.OnInit(e);

        if(!IsPostBack) {
            _IsSettingPrimaryPhotoMode = false;
        }

        _LoadGalleryImages();
    }
}

Метод _LoadGalleryImages

private void _LoadGalleryImages() {
    PhotoGalleryImageCollection images = PhotoGalleryImages.GetPhotoGalleryImages();

    foreach(PhotoGalleryImage image in images) {
        ImageButton displayImage = new ImageButton();
        Panel panel = new Panel();
        panelPhotoContainer.Controls.Add(panel);
        displayImage.ImageUrl = "some URL";

        if(!_IsSettingPrimaryPhotoMode) {
            displayImage.OnClientClick = "showPopup(); return false;";
        }
        else {
            displayImage.Command += new CommandEventHandler(displayImage_Command);
            displayImage.CommandName = "ImageButton" + image.PhotoGalleryImageId.ToString();
            displayImage.CommandArgument = image.PhotoGalleryImageId.ToString();
        }

        panel.Controls.Add(displayImage);
    }
}

btnSetPrimaryPhoto_Click

protected void btnSetPrimaryPhoto_Click(object sender, EventArgs e) {
    // if I don't call this, duplicate controls will be added since they were added
    // from OnInit calling _LoadGalleryImages();
    panelPhotoContainer.Controls.Clear();
    _IsSettingPrimaryPhotoMode = true;
    // reload since _IsSettingPrimaryPhotoMode has now changed
    _LoadGalleryImages();
}

Что я делаю не так?

Ответы [ 3 ]

3 голосов
/ 23 февраля 2012

Полагаю, проблема может быть вызвана тем, что вы не установили ID s динамически создаваемых элементов управления.Это очень важно, так как используется в процессе запуска событий post back.Значение ID для каждого из элементов управления должно быть постоянным и не меняться между постбэками.

Вы можете попробовать изменить свой метод _LoadGalleryImages() следующим образом:

private void _LoadGalleryImages() {
    PhotoGalleryImageCollection images = PhotoGalleryImages.GetPhotoGalleryImages();

    int imageCtrlCounter = 0;
    foreach(PhotoGalleryImage image in images) {
        ImageButton displayImage = new ImageButton() { ID = String.Format("myDisplayImage{0}", imageCtrlCounter) };
        Panel panel = new Panel();
        panelPhotoContainer.Controls.Add(panel);
        displayImage.ImageUrl = "some URL";

        if(!_IsSettingPrimaryPhotoMode) {
            displayImage.OnClientClick = "showPopup(); return false;";
        }
        else {
            displayImage.Command += new CommandEventHandler(displayImage_Command);
            displayImage.CommandName = "ImageButton" + image.PhotoGalleryImageId.ToString();
            displayImage.CommandArgument = image.PhotoGalleryImageId.ToString();
        }

        panel.Controls.Add(displayImage);
        imageCtrlCounter++;
    }
}
3 голосов
/ 23 февраля 2012

Это должно быть что-то, связанное с первоначальным оповещением о событии, потому что проблема возникает только в первый раз.Отличие этого времени в том, что _LoadGalleryImages вызывается дважды (один раз в init и один раз в обработчике нажатия кнопки), поэтому я думаю, что что-то там не очищается, когда вы очищаете панель контейнера и снова вызываете _LoadGalleryImages при нажатии кнопки.обработчик.

Почему бы не попробовать эту альтернативу: вызывать LoadImageGalleries только один раз за цикл страницы (в init).

Вместо очистки элементов управления и повторного вызова LoadGalleryImages в той же обратной передаче (в кнопкесобытие щелчка), при нажатии кнопки вызывается метод, который выполняет итерацию по элементам управления изображениями, которые вы уже создали при вызове LoadGalleryImages, и настраивает их:

1) Удалите щелчок по клику (очистите его).

2) Присоединить событие.

1 голос
/ 24 февраля 2012

@ swannee
На самом деле, твой метод сработал после того, как я об этом подумал.Теперь я вызываю _LoadGalleryImages для каждого OnInit.Я понимаю, что это много повторяющегося кода, который можно объединить.

Новый _LoadGalleryImages

private void _LoadGalleryImages() {
    PhotoGalleryImageCollection images = PhotoGalleryImages.GetPhotoGalleryImages();

    foreach(PhotoGalleryImage image in images) {
        Panel panel = new Panel();
        panelPhotoContainer.Controls.Add(panel);

        ImageButton displayImage = new ImageButton();
        panel.Controls.Add(displayImage);
        displayImage.ID = string.Format("ImageButton{0}", image.PhotoGalleryImageId);
        displayImage.ImageUrl = "Some URL";
        displayImage.AlternateText = displayImage.ToolTip = image.ImageName;

        if(!_IsSettingPrimaryPhotoMode) {
            displayImage.OnClientClick = "showPopup(); return false;";
        }
        else {
            // handles the image button command wireup
            displayImage.Command += new CommandEventHandler(displayImage_Command);
            displayImage.CommandArgument = image.PhotoGalleryImageId.ToString();
        }
    }
}



Я добавил новый метод, поскольку выпредложил найти элементы управления, так как они уже были созданы в OnInit, и мне просто нужно найти их после нажатия кнопки и очистить OnClientClick.

private void _LoadSelectPrimaryImages() {
    PhotoGalleryImageCollection images = PhotoGalleryImages.GetPhotoGalleryImages();

    foreach(PhotoGalleryImage image in images) {
        Control control = panelPhotoContainer.FindControl(string.Format("ImageButton{0}", image.PhotoGalleryImageId));

        if(control != null) {
            ImageButton displayImage = (ImageButton)control;
            displayImage.OnClientClick = "";
        }
    }
}



У меня также есть кнопка отмены для возврата кнопок изображения к тому, как они были раньше, для отображения всплывающего окна.

private void _ResetGalleryImages() {
    PhotoGalleryImageCollection images = PhotoGalleryImages.GetPhotoGalleryImages(_photoGalleryId, false, true);

    foreach(PhotoGalleryImage image in images) {
        Control control = panelPhotoContainer.FindControl(string.Format("ImageButton{0}", image.PhotoGalleryImageId));

        if(control != null) {
            ImageButton displayImage = (ImageButton)control;
            displayImage.ImageUrl = "Original URL";
            displayImage.OnClientClick = "showPopup(); return false;";
        }
    }
}



и два нажатия кнопки страницы

protected void btnSetPrimaryPhoto_Click(object sender, EventArgs e) {
    _IsSettingPrimaryPhotoMode = true;
    _LoadSelectPrimaryImages();
}



protected void btnCancelSetPrimaryPhoto_Click(object sender, EventArgs e) {
    _IsSettingPrimaryPhotoMode = false;
    _ResetGalleryImages();
}



Кто-то сказал в ответ ранее ...похоже, что ответ был удален ... для очистки элементов управления в _LoadGalleryImages, таких как:

private void _LoadGalleryImages() {
    panelPhotoContainer.Controls.Clear();
    PhotoGalleryImageCollection images = PhotoGalleryImages.GetPhotoGalleryImages();

    foreach(PhotoGalleryImage image in images) {
        ImageButton displayImage = new ImageButton();
        Panel panel = new Panel();
        panelPhotoContainer.Controls.Add(panel);
        displayImage.ImageUrl = "some URL";

        if(!_IsSettingPrimaryPhotoMode) {
            displayImage.OnClientClick = "showPopup(); return false;";
        }
        else {
            displayImage.Command += new CommandEventHandler(displayImage_Command);
            displayImage.CommandName = "ImageButton" + image.PhotoGalleryImageId.ToString();
            displayImage.CommandArgument = image.PhotoGalleryImageId.ToString();
        }

        panel.Controls.Add(displayImage);
    }
}



, что также работает, но я думаю, что это может быть более неэффективнымчем ваш метод, @swannee.Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...