2012-02-23 50 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

相關問題