C# 动态添加的ImageButton命令事件在第二次单击之前不会触发
我有一个动态添加ImageButtons的页面。我首先设置按钮的C# 动态添加的ImageButton命令事件在第二次单击之前不会触发,c#,asp.net,.net,page-lifecycle,C#,Asp.net,.net,Page Lifecycle,我有一个动态添加ImageButtons的页面。我首先设置按钮的OnClientClick,以简单地显示放大的图像弹出窗口,并返回false,表示不回发 我在页面上有一个设置“主图像”的按钮,因此当单击此按钮时,我会设置一个名为\u IsSettingPrimaryPhotoMode=true的属性,调用函数重新创建ImageButtons,并且在创建ImageButtons时,如果此属性为true,而不是在客户端单击时添加,我连接了一个CommandEventHandler,这样我就可以通过读
OnClientClick
,以简单地显示放大的图像弹出窗口,并返回false,表示不回发
我在页面上有一个设置“主图像”的按钮,因此当单击此按钮时,我会设置一个名为\u IsSettingPrimaryPhotoMode=true
的属性,调用函数重新创建ImageButtons,并且在创建ImageButtons时,如果此属性为true,而不是在客户端单击时添加,我连接了一个CommandEventHandler
,这样我就可以通过读取CommandArgument
来判断单击了哪个按钮
问题是,事件处理程序不会在第一次单击图像时启动,而只会在第二次单击后启动。我还将代码从Page\u Load
移动到OnInit
,并在每次回发时加载图像按钮
我将\u IsSettingPrimaryPhotoMode
保存到会话中
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;
}
}
这一页在上面
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_单击
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();
}
我做错了什么?它必须与初始事件wireup相关,因为问题只在第一次发生。这段时间的不同之处在于_LoadGalleryImages被调用了两次(一次在init中,一次在button click事件处理程序中),因此我认为当您清除容器面板并再次在按钮的click处理程序中调用_LoadGalleryImages时,那里的某些内容没有得到清理
为什么不试试这个替代方案:
每个页面周期仅调用LoadImageGalleries一次(在init中)
与在同一回发中(在button click事件中)清除控件并再次调用LoadGalleryImage不同,在button click上调用一个方法,该方法迭代调用LoadGalleryImage时已创建的图像控件并调整它们:
1) 卸下onclientclick(将其清除)
2) 附加事件。我想问题可能是因为您没有设置动态创建控件的ID
s。这是非常重要的,因为它用于启动后返回事件的过程。每个控件的ID
值应该是常量,并且在回发之间不会改变
您可以尝试修改\u 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++;
}
}
@斯旺尼
事实上,在我仔细考虑之后,你的方法确实奏效了。我现在确实在每个OnInit上调用LoadGalleryImage。我意识到这是许多可以合并的重复代码
新加载的GalleryImage
我按照您的建议添加了一个新方法来查找控件,因为它们已经在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 btnCancelSetPrimaryPhoto_Click(object sender, EventArgs e) {
_IsSettingPrimaryPhotoMode = false;
_ResetGalleryImages();
}
然后单击两个页面按钮
protected void btnSetPrimaryPhoto_Click(object sender, EventArgs e) {
_IsSettingPrimaryPhotoMode = true;
_LoadSelectPrimaryImages();
}
protected void btnCancelSetPrimaryPhoto_Click(object sender, EventArgs e) {
_IsSettingPrimaryPhotoMode = false;
_ResetGalleryImages();
}
有人在早些时候的回复中说…看起来响应已被删除…以清除LoadGallery图像中的控件,例如:
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);
}
}
protected void btnCancelSetPrimaryPhoto_Click(object sender, EventArgs e) {
_IsSettingPrimaryPhotoMode = false;
_ResetGalleryImages();
}
这也行,但我认为这可能比你的方法效率更低,@swannee。谢谢 同时尝试添加此代码,看看它是否能纠正您的问题displayImage.Command-=newcommandeventhandler(displayImage_命令);为什么要在按钮单击和另一个事件中调用_LoadGalleryImages()?我认为这不起作用,因为控件是动态添加的。我尝试遍历页面控件,但它们不存在,因为它们是在OnInit中的if(!IsPostBack){}上添加的,但在单击页面按钮后就不存在了。我认为有必要总是在OnInit中调用_loadGalleryImage,这样每次DOM和页面状态都是相同的。问题是我没有向控件添加ID。不确定您是否理解我的响应,我不是说只调用它一次……我是说每个页面周期(在init中)只调用它一次。但只要修复有效……太好了!我现在明白你的意思了。在答案中看到我的解决方案。我不知道我没有足够的声誉来回答我自己的问题而不等待8个小时。请稍后查看我的解决方案。有趣的是,好的,我将等待答案。问题是没有设置ID。这是问题的一部分,但@swannee的解决方案是完整的答案,因此我标记了他的答案,但单击您的答案是有帮助的。哦,我明白了,我看不到对我的答案的任何赞成票(不过,可能会有一些延迟)。不管怎么说,你修好了就好了:)。@Lucas:我本来会给你一次撞击,但我今天已经把我的撞击量最大了……明天我会给你一次。@swannee:谢谢,因为你提到的事情帮助解决了这个问题,我也给了你一次投票:)。