2012-10-29 25 views
2

給出以下代碼,單擊每個元素時出現問題。如果我們假設我有5個練習,因此在foreach()循環中創建了5個元素,當表格呈現時,我單擊任何元素,委託始終獲得第5個元素(最後一個元素)的鍛鍊。Monotouch.Dialog StyledStringElement委託始終觸發添加的最後一個元素

元素顯示正確,每個元素都顯示相關練習的名稱。只是代表不能按預期工作。

如果我不使用foreach循環並硬編碼每個元素,它會按預期工作。但是,如果我不能動態填充dialogViewController並使用每個元素點擊事件,那就不好。

private void CreateExerciseTable() 
{ 
Section section = new Section(); 

foreach (var exercise in exercises) 
{ 
    var element = new StyledStringElement(exercise.ExerciseName, 
     delegate { AddExercise(exercise); }) 
     { 
      Font = Fonts.H3, 
      TextColor = UIColor.White, 
      BackgroundColor = RGBColors.LightBlue, 
      Accessory = UITableViewCellAccessory.DisclosureIndicator 
     }; 

    section.Elements.Add(element); 
} 

var root = new RootElement("Selection") { 
    section 
}; 

var dv = new DialogViewController(root, true); 
dv.Style = UITableViewStyle.Plain; 

//Remove the extra blank table lines from the bottom of the table. 
UIView footer = new UIView(new System.Drawing.RectangleF(0,0,0,0)); 
dv.TableView.TableFooterView = footer; 

dv.TableView.SeparatorColor = UIColor.White; 
dv.TableView.BackgroundColor = UIColor.White; 
tableFitnessExercises.AddSubview(dv.View);  
} 

private void AddExercise(FitnessExercise exercise) 
{ 
NavigationManager.FitnessRoutine.Add(exercise); 
PerformSegue(UIIdentifierConstants.SegAddExerciseToFitnessRoutine, this); 
} 

回答

8

這是一個經典的閉包bug!

問題是您正在訪問循環引用。

嘗試:

foreach (var exercise in exercises) 
{ 
    var localRef = exercise; 
    var element = new StyledStringElement(exercise.ExerciseName, 
     delegate { AddExercise(localRef); }) 
     { 
      Font = Fonts.H3, 
      TextColor = UIColor.White, 
      BackgroundColor = RGBColors.LightBlue, 
      Accessory = UITableViewCellAccessory.DisclosureIndicator 
     }; 

    section.Elements.Add(element); 
} 

有關這方面看到http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx

+0

嗯,我想我從來沒有過這種事發生在我身上。即使經過了這麼多年的發展,也是一個新手的錯誤。感謝你的回答。它工作正常! – Apollonas

+0

公平起見,我現在只注意到它,因爲Resharper提醒我,因爲我一直在寫JavaScript代碼。請注意,來自Eric Lippert的鏈接 - 在C#5中更改的代碼 - 因此在C#5中,您的原始代碼將起作用 – Stuart

+1

如果我可以不止一次地對此進行投票,我會......同樣的問題。非常感謝你的回答。你節省了我不得不實施不同解決方案的時間!多謝了! – BRogers

相關問題