动态添加的ImageButton Command事件在第二次单击之前不会触发

时间:2012-02-23 17:34:02

标签: c# asp.net .net page-lifecycle

我有一个页面,我可以动态添加ImageButtons。我首先设置按钮的OnClientClick以简单地显示放大的图像的弹出窗口,并返回false而不回发。

我在页面上有一个按钮来设置"主要图像"因此,当单击此按钮时,我设置一个名为_IsSettingPrimaryPhotoMode = true的属性,调用该函数重新创建ImageButtons,并在创建ImageButtons时如果此属性为true而不是添加OnClientClick,我挂钩{ {1}}所以我可以通过阅读CommandEventHandler来判断点击了哪个按钮。

问题是事件处理程序在第一次点击图像时不会触发,但仅在第二次点击时触发。我还将代码从CommandArgument移到Page_Load,并在每次回发时加载ImageButtons。

我将OnInit保存到_IsSettingPrimaryPhotoMode

Session

OnInit页面

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;
    }
}

_LoadGalleryImages方法

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

        if(!IsPostBack) {
            _IsSettingPrimaryPhotoMode = false;
        }

        _LoadGalleryImages();
    }
}

btnSetPrimaryPhoto_Click

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);
    }
}

我做错了什么?

3 个答案:

答案 0 :(得分:3)

它必须与初始事件连线有关,因为问题只在第一次发生。那段时间的不同之处在于_LoadGalleryImages被调用了两次(一次在init中,一次在按钮点击事件处理程序中)所以我认为当你清空容器面板并在按钮单击中再次调用_LoadGalleryImages时,某些东西没有得到清理处理程序。

为什么不试试这个选择: 每页循环只调用一次LoadImageGalleries(在init中)。

而不是清除控件并在同一回发中再次调用LoadGalleryImages(在按钮单击事件中),在按钮上单击调用一个方法,该方法迭代调用LoadGalleryImages时已创建的图像控件并调整它们:

1)删除onclientclick(清除它)。

2)附上活动。

答案 1 :(得分:3)

我认为这个问题可能是因为你没有设置ID动态创建的控件。这非常重要,因为它在发布回发事件的过程中使用。每个控件的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++;
    }
}

答案 2 :(得分:1)

@swannee
实际上,在我考虑更多之后,你的方法确实有效。我现在在每个OnInit上调用_LoadGalleryImages。我意识到这是很多可以合并的重复代码。

新的_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中创建了它们,因为它们已经在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。谢谢!