2012-02-23 153 views
2

我有一个页面,我动态添加ImageButtons。我首先设置了按钮的OnClientClick,以简单地显示放大图像的弹出窗口,并返回false,无回传。动态添加ImageButton命令事件不会触发,直到第二次点击

我在页面上有一个按钮来设置“主图像”,所以当点击这个按钮时,我设置一个名为_IsSettingPrimaryPhotoMode = true的属性,调用该函数重新创建ImageButtons,并且在创建ImageButton时,如果此属性为true添加一个OnClientClick,我连接CommandEventHandler,所以我可以通过阅读CommandArgument来分辨哪个按钮被点击了。

问题是事件处理程序不会在第一次点击图像时触发,而只会在第二次点击之后触发。我还将代码从Page_Load移至OnInit,并在每次回传中加载ImageButton。我们将_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(); 
} 

我在做什么错?

+0

尝试添加此代码,看看它是否会解决您的问题displayImage.Command - = new CommandEventHandler(displayImage_Command); – MethodMan 2012-02-23 17:43:47

+0

为什么在按钮点击和另一个事件中调用_LoadGalleryImages()? – 2012-02-23 18:42:12

回答

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中创建和我需要的只是按钮后,找他们点击并清除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更无效。谢谢!

3

它必须与初始事件连接有关,因为问题只发生在第一次。这段时间的不同之处在于_LoadGalleryImages被调用两次(一次在init中,一次在按钮单击事件处理程序中),所以我认为在清除容器面板时再次调用_LoadGalleryImages时,处理程序。

为什么不尝试这种替代方法: 每个页面周期只调用一次LoadImageGalleries(在init中)。

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

1)删除onclientclick(清除它)。

2)附加事件。

+0

我不认为这将工作,因为控件是动态添加的。我尝试通过页面控件迭代,并且它们不存在,因为它们添加在OnInit中的if(!IsPostBack){}上,但它们在页面按钮单击后不存在。我认为总是在OnInit中调用_LoadGalleryImages是必要的,所以DOM和页面状态每次都是相同的。 问题是我没有将ID添加到控件。 – 2012-02-23 20:30:11

+0

不知道你理解我的回应,我并不是说只调用一次...我的意思是每个页面循环只调用一次(在init中)。但只要修复工作...很好! – swannee 2012-02-23 20:32:17

+0

我明白你的意思了。在答案中看到我的解决方案。 – 2012-02-23 22:10:46

2

我想这个问题可能是由于您没有设置动态创建的控件的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++; 
    } 
} 
+0

不设置ID是问题。 – 2012-02-23 22:14:20

+0

这是问题的一部分,但@swannee的解决方案是完整的答案,所以我标记了他的答案,但点击了你的帮助。 – 2012-02-23 22:35:12

+0

哦,我明白了,我的回答中看不到任何upvotes(但可能会有一些延迟)。无论如何,这是很好,你修复它:)。 – 2012-02-23 22:37:15

相关问题