如何从UITableView RowSelect Event Monottouch访问主UIViewController

本文关键字:Monottouch 访问 UIViewController Event RowSelect UITableView | 更新日期: 2023-09-27 18:00:23

我的主ViewController上有一个UITAbleView。表视图是如下所示的子类。当用户选择一行时,我想通过调用主ViewController上的例程来切换到新视图。然而,我无法从子类访问我的主视图控制器。我该怎么做?

public class TableSource : UITableViewSource
{
    string[] tableItems;
    string cellIdentifier = "TableCell";
    public TableSource(string[] items)
    {
        tableItems = items;
    }
    public override int RowsInSection(UITableView tableview, int section)
    {
        return tableItems.Length;
    }
    public override UITableViewCell GetCell(UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
    {
        UITableViewCell cell = tableView.DequeueReusableCell(cellIdentifier);
        if (cell == null)
            cell = new UITableViewCell(UITableViewCellStyle.Default, cellIdentifier);
        cell.TextLabel.Text = tableItems[indexPath.Row];
        return cell;
    }
    public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
    {
        new UIAlertView("Row Selected", tableItems[indexPath.Row], null, "OK", null).Show();
        tableView.DeselectRow(indexPath, true);
        //Call routine in the main view controller to switch to a new view
    }
}

如何从UITableView RowSelect Event Monottouch访问主UIViewController

我在发现并评论了一篇类似的帖子后,偶然发现了这篇帖子:Xamarin UITableView行选择

虽然将UIViewController的实例传递给TableSource是解决此问题的一种方法,但它也有缺点。主要是您已经将TableSource与特定类型的UIViewController紧密耦合。

相反,我建议在UITableViewSource中创建一个EventHandler,如下所示:

public event EventHandler ItemSelected;

我还将为所选项目设置一个getter属性:

private selectedItem
public MyObjectType SelectedItem{
    get{
        return selectedItem;
    }
}

然后我会更新RowSelected方法,如下所示:

public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
    selectedItem = tableItems[indexPath.Row];
    ItemSelected(this, EventArgs.Empty);
}

然后,您的UIViewController可以监听ItemSelected事件并执行它所需要的任何操作。这允许您为多个视图和视图控制器重用UITableViewSource。

将其添加到.ctor中,例如

public TableSource(string[] items)

变为:

public TableSource(string[] items, UIViewController ctl)

然后保留一个参考:

public TableSource(string[] items, UIViewController ctl)
{
    tableItems = items;
    controller = ctl;
}

并在您的RowSelected呼叫中使用:

public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
    new UIAlertView("Row Selected", tableItems[indexPath.Row], null, "OK", null).Show();
    tableView.DeselectRow(indexPath, true);
    controller.DoWhatYouNeedWithIt ();
}

NSNotifications可能是另一种选择。

因此,在RowSelected中,您发布了一个通知:

NSNotificationCenter.DefaultCenter.PostNotificationName("RowSelected", indexPath);

在视图控制器中,您为通知添加了一个观察器:

public override void ViewDidLoad()
{
    base.ViewDidLoad();    
    NSNotificationCenter.DefaultCenter.AddObserver(new NSString("RowSelected"), RowSelected);
}
void RowSelected(NSNotification notification) 
{
    var indexPath = notification.Object as NSIndexPath;
    // Do Something
}