1

我的主 ViewController 上有一个 UITableView。Tableview 是子类,如下所示。当用户选择一行时,我想通过调用主 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

    }

}
4

3 回答 3

3

在找到并评论了类似的帖子后,我碰巧看到了这篇帖子: Xamarin UITableView RowSelection

虽然将 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。

于 2013-08-16T12:36:09.317 回答
1

将其添加到您的 .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 ();
}
于 2013-02-21T17:52:04.743 回答
1

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
}
于 2016-11-08T19:46:11.160 回答