2012-09-10 170 views
2

我已使用按鈕自定義了我的表格視圖單元附件。一切都很好,直到事件處理。單擊按鈕中的事件處理程序問題

這是我的代碼。 [編輯]

public class ProductTableSource: UITableViewSource 
    { 
     protected List<Product> tableItems = new List<Product>(); 
     protected string cellIdentifier = "producdetailscell"; 
     private RootViewController controller; 
     protected Transaction transaction; 
     public UIButton addItemButton; 
     public UIImage Image; 



     public ProductTableSource (List<Product> items, RootViewController controller) 
     { 
      this.tableItems = items; 
      this.controller = controller;  
      Image = UIImage.FromFile ("Images/plus.png"); 
      addItemButton = UIButton.FromType(UIButtonType.Custom); 
      var buttonFrame = new RectangleF (0f, 0f, Image.Size.Width, Image.Size.Height); 
      addItemButton.Frame = buttonFrame; 
      addItemButton.SetImage(Image, UIControlState.Normal); 
      addItemButton.TouchUpInside += delegate { 
       Console.WriteLine ("Touched"); 

      }; 

     } 

     public void setTableItem (List<Product> tableItems) 
     { 

      this.tableItems = tableItems; 
     } 

     /// <summary> 
     /// Called by the TableView to determine how many cells to create for that particular section. 
     /// </summary> 
     public override int RowsInSection (UITableView tableview, int section) 
     { 
      return tableItems.Count; 
     } 

     /// <summary> 
     /// Called when a row is touched 
     /// </summary> 

     public override void AccessoryButtonTapped (UITableView tableView, NSIndexPath indexPath) 
     { 

      var prod = controller.Productdetails[indexPath.Row]; 
      Double amount = 1*prod.SellingPriceA; 
      transaction = new Transaction(); 
      transaction.SetTransaction(controller.CustomerID, prod.ID, prod.Description1,1, prod.SellingPriceA,0.0,amount); 
      controller.UpdateOrderedItemsTableView(); 

     } 


     /// <summary> 
     /// Called by the TableView to get the actual UITableViewCell to render for the particular row 
     /// </summary> 
     public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) 
     { 
      // request a recycled cell to save memory 
      UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier); 
      // if there are no cells to reuse, crate a new one 
      if (cell == null) { 
       cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier); 
      } 

      var cust = controller.Productdetails [indexPath.Row]; 
      cell.TextLabel.Text = cust.Description1; 


      cell.AccessoryView = this.controller.addItemButton; 

      return cell; 
     } 



    } 

這是我得到的錯誤。不知道發生了什麼事。也許我使用了不合適的功能請建議我!

**Stacktrace: 

    at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff> 
    at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
    at SalesOrder.Application.Main (string[]) [0x00000] in /Users/Mac/Projects/SalesOrderPolarisnet/SalesOrder/Main.cs:17 
    at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff> 

Native stacktrace: 

    0 SalesOrder       0x000908cc mono_handle_native_sigsegv + 284 
    1 SalesOrder       0x000056f8 mono_sigsegv_signal_handler + 248 
    2 libsystem_c.dylib     0x9613559b _sigtramp + 43 
    3 ???         0xffffffff 0x0 + 4294967295 
    4 UIKit        0x022620e6 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61 
    5 UIKit        0x02308ade -[UIControl sendAction:to:forEvent:] + 66 
    6 UIKit        0x02308fa7 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 503 
    7 UIKit        0x02307d8a -[UIControl touchesBegan:withEvent:] + 264 
    8 UIKit        0x02523a1a _UIGestureRecognizerUpdate + 6725 
    9 CoreFoundation      0x011b099e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 
    10 CoreFoundation      0x01147640 __CFRunLoopDoObservers + 384 
    11 CoreFoundation      0x011134c6 __CFRunLoopRun + 1174 
    12 CoreFoundation      0x01112d84 CFRunLoopRunSpecific + 212 
    13 CoreFoundation      0x01112c9b CFRunLoopRunInMode + 123 
    14 GraphicsServices     0x048307d8 GSEventRunModal + 190 
    15 GraphicsServices     0x0483088a GSEventRun + 103 
    16 UIKit        0x0225f626 UIApplicationMain + 1163 
    17 ???         0x0d4d41f4 0x0 + 223166964 
    18 ???         0x0d4d2f50 0x0 + 223162192 
    19 ???         0x0d4d27c0 0x0 + 223160256 
    20 ???         0x0d4d284f 0x0 + 223160399 
    21 SalesOrder       0x00009ab2 mono_jit_runtime_invoke + 722 
    22 SalesOrder       0x0016b34e mono_runtime_invoke + 126 
    23 SalesOrder       0x0016f4d4 mono_runtime_exec_main + 420 
    24 SalesOrder       0x001748c5 mono_runtime_run_main + 725 
    25 SalesOrder       0x00066cb5 mono_jit_exec + 149 
    26 SalesOrder       0x00203911 main + 2209 
    27 SalesOrder       0x00002ab5 start + 53 

================================================================= 
Got a SIGSEGV while executing native code. This usually indicates 
a fatal error in the mono runtime or one of the native libraries 
used by your application. 
=================================================================** 

回答

2

Mono的GC可能會收集和處理您的UIButtons,因爲它們被聲明爲局部變量。我建議你繼承UITableViewCell,包括UIButton,然後在GetCell中使用該類。

順便說一下,最好使用TouchUpInside代替TouchDown事件。

+0

嗨其實,我試了一下沒有工作。我真的需要這個自定義按鈕。 – Akrambek

+0

您是否試圖創建子類並使用自定義的UITableViewCell?那種方法有什麼問題? –

+0

好的THAnk你非常非常,經過兩天1天,你的建議修復了發行 – Akrambek

4

當您的GetCell方法返回cell實例不再有任何管理參考。此時GC可以收集它。

然而本地部分你UITableViewCell仍然存在(他們本身引用),所以它會很好 - 但是當你使用事件處理它試圖要回管理代碼...和那不再存在(它會崩潰)。

有幾種方法可以解決這個問題。一個簡單的方法是保留對您創建的每個cell的引用,例如將它們添加到靜態List<UITableViewCell>。 GC將無法收集它們,以便事件處理程序稍後可以使用。

但是,您的代碼可能更好的是重新使用單元格。現在,您正在重新使用UITableViewCell,但不是它的內容,即您始終創建UIImageUIButton。您可以輕鬆地共享它們(至少是UIImage)並節省內存。您也可以只保留對按鈕的引用(而不是整個單元格),並在解決問題的同時節省內存。

編輯:這是怎麼這應該是這樣的:

static UIImage shared_image = UIImage.FromFile ("Images/plus.png"); 
    static List<UITableViewCell> cells = new List<UITableViewCell>(); 

    public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) 
    { 
     UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier); 
     if (cell == null) { 
      // create a cell that will be reused (some initialization steps skipped) 
      cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier); 
      var addItemButton = UIButton.FromType (UIButtonType.Custom); 
      // the same image can be shared in all cells to save memory 
      addItemButton.SetImage (shared_image, UIControlState.Normal); 
      addItemButton.TouchUpInside += delegate { 
       Console.WriteLine ("Touched"); 
      }; 
      cell.AccessoryView = addItemButton; 
      // keep a reference to the cells so they won't be GC'ed 
      /// that will ensure you can call back (event handler) into the managed instance 
      cells.Add (cell); 
     } 
     // customize the cell - you should not be adding elements here 
     // otherwise they will be added each time the cell is shown (not created) 
     cell.TextLabel.Text = indexPath.Row.ToString(); 
     return cell; 
    } 
+0

非常感謝你的建議。因爲我有大量的數據。我必須重新使用細胞。所以我做的是在tableource類的構造函數中。我定義了全局UIButton。但是,當我將它分配給單元格時,它不會顯示出來。不知道什麼是問題。我定義按鈕的方式就像我把它放在上面的源代碼中。任何想法可能會出錯 – Akrambek

+0

好吧,現在它工作,但只顯示在最後一行。 – Akrambek

+0

我已更新我的TableSource類。我的意思是 – Akrambek

相關問題