1

I'm trying to capture and handle an event when an element of a UITableViewSource is clicked.
Here's my code:

    public class TableViewSource : UITableViewSource
    {
        public event EventHandler<SongSelectedEventArgs> SongSelected;
        private List<Song> rows;

        public TableViewSource (List<Song> list) 
        { 
            rows = list; 
        }

        public override int RowsInSection (UITableView tableview, int section) 
        { 
            return rows.Count; 
        }

        public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
        {
            // raise our event
            var handler = SongSelected;
            if (handler != null)
                handler (this, new SongSelectedEventArgs (rows[indexPath.Row]));
        }

        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {  
            UITableViewCell cell = new UITableViewCell(UITableViewCellStyle.Default,"mycell"); 
            cell.TextLabel.Text = rows[indexPath.Row].ToString();
            return cell;
        }

        public class SongSelectedEventArgs : EventArgs
        {
            public Song Group { get; set; }
            public SongSelectedEventArgs(Song group) : base()
            { Group = group; }
        }
    }

I'm modeling from an example piece from Xamarin, here:

    protected class AssetGroupTableSource : UITableViewSource
    {
        public event EventHandler<GroupSelectedEventArgs> GroupSelected;
        protected List<ALAssetsGroup> groups;

        public AssetGroupTableSource(List<ALAssetsGroup> groups) { this.groups = groups; }

        public override int NumberOfSections (UITableView tableView) { return 1; }

        public override int RowsInSection (UITableView tableview, int section) { return groups.Count; }

        public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
        {
            UITableViewCell cell = tableView.DequeueReusableCell ("AlbumCell");
            if(cell == null)
                cell = new UITableViewCell (UITableViewCellStyle.Default, "AlbumCell");
            cell.TextLabel.Text = groups[indexPath.Row].Name;
            return cell;
        }

        public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
        {
            // raise our event
            var handler = GroupSelected;
            if (handler != null)
                handler (this, new GroupSelectedEventArgs (groups[indexPath.Row]));
        }

        public class GroupSelectedEventArgs : EventArgs
        {
            public ALAssetsGroup Group { get; set; }
            public GroupSelectedEventArgs(ALAssetsGroup group) : base()
            { Group = group; }
        }
    }

When I click on an element (of class Song) in the table view, it successfully goes to the override RowSelected. However, the handler is always null. What am I doing differently from the example code that is causing this to fail?

EDIT: Here is the line that should read the event (but isn't triggering):

    TableViewSource tableData = new TableViewSource(results);

        tableData.SongSelected += (object sender, TableViewSource.SongSelectedEventArgs e) => {
            //AssetEnumerationScreen assetScreen = new AssetEnumerationScreen (e.Group.Name, assetGroups[e.Group]);
            //NavigationController.PushViewController (assetScreen, true);
            Console.WriteLine("Test");
        };

EDIT: Here is most of the main body code:

    TableViewSource tableData = new TableViewSource(results);

        tableData.SongSelected += (object sender, TableViewSource.SongSelectedEventArgs e) => {
            Console.WriteLine("Test");
        };

        tableData.SongSelected += delegate(object sender, TableViewSource.SongSelectedEventArgs e) {
            Console.WriteLine("Test");
            LyricsScreen assetScreen = new LyricsScreen (e.Song);
            NavigationController.PushViewController (assetScreen, true);
        };
        searchBool.ValueChanged += (sender, e) => {
            UpdateDisplay(tableData, songList);
        };
        lyricSearch.TextChanged += (sender, e) => {
            UpdateDisplay(tableData, songList);
        };

        lyricSearch.Text = String.Empty;

        this.searchResults.Source = tableData;

EDIT!: I found the mistake. I had this line:

    tableData = new TableViewSource(results);

twice, so it subscribes the first one to the event, but then I created a new one and set that one to the source, overwriting the one with the subscription.

Thanks!

Adam
  • 488
  • 6
  • 19
  • 3
    Nowhere in your code do I see where you would assign a handler to SongSelected. Something like: var source = new TableViewSource(list); source.SongSelected += () => Console.WriteLine("SongSelected"); – Krumelur Dec 05 '12 at 07:37
  • I had it later in the code. I was just posting the class definitions up there. I have added the line you asked for in the original post – Adam Dec 07 '12 at 02:42
  • 2
    Are you properly assigning the TableViewSource to the UITableView? Also, make sure not to also set the UITableView's Delegate or DataSource properties as those will replace the Source – jstedfast Dec 07 '12 at 04:56
  • @Adam Still I'm missing something like tableView.Source = tableData, which will assign your source to the table view. Also see jstedfast's comment. – Krumelur Dec 07 '12 at 11:14
  • For both of you, the 2nd edit has most of the remaining code that assigns the source. I have two attempts at subscribing (because I wasn't sure which was better), but neither work. Also, regarding jstedfast's second comment, I'm not sure if I understand it correctly, but I don't think I did that? – Adam Dec 09 '12 at 23:08
  • I got it, guys. Turns out it was an incredibly stupid mistake (as usual). It's explained in the final edit of the original post, if you're curious. Thanks for all of the help! Jstedfast was right, as I was replacing the source after subscribing. If you want to submit the answer, I can accept it. Or, I'll do it in a day or so if you haven't. – Adam Dec 10 '12 at 01:09

0 Answers0