Вызовите метод и передайте данные из контроллера представления B для просмотра контроллера A в Xamarin.iOS

1

У меня есть контроллер A, где я получаю некоторые значения. При определенных обстоятельствах пользователь должен выбрать значение, если доступно несколько. Поэтому я представляю другой контроллер представления B (UITableView), где я позволяю пользователю выбирать запись. Как я могу вызвать метод из A, когда я сейчас на B? (во избежание дублирования кода) И как передать некоторые параметры в этом методе?

Я читал о делегатах/протоколах, событиях (стиль.NET) и центре уведомлений. Каков наилучший способ передать строку и вызвать метод из A? Не могли бы вы привести пример? В примере из Xamarin нет примера того, как определить собственный протокол.

Или я должен сделать поле из A public и передать это поле для просмотра контроллера B, где я работаю с данными?

Теги:
xamarin
xamarin.ios

1 ответ

2
Лучший ответ

Мероприятия

Мне удалось активировать мероприятие. Моя информация была основана на следующих ссылках:

В моем UITableViewController (контроллер просмотра B) я добавил следующее:

// class variable  
public event EventHandler<BLevelSelectedEventArgs> BLevelSelected;

// event handler
public class BLevelSelectedEventArgs : EventArgs
{
    public BLevelItem bLevel { get; set; }

    public BLevelSelectedEventArgs(BLevelItem bLevel) : base()
    { 
        this.bLevel = bLevel;
    }
}

Здесь определяется событие, а также настраиваемый обработчик событий. Вы можете определить свойства, которые вы хотите транспортировать, с помощью события, например, строки. Здесь используется пользовательский BLevelItem. Имя обработчика события и имя события должны быть изменены для вашего приложения. В этом классе UITableViewController меня также определен UITableViewSource.

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
    tableView.DeselectRow (indexPath, true); // iOS convention is to remove the highlight

    if (this.controller.BLevelSelected != null) {
        this.controller.BLevelSelected (this, new BLevelSelectedEventArgs (controller.bLevelList[indexPath.Row]));
    }

}

Здесь событие возбуждается, и параметр передается с событием. Теперь отсутствует только один прослушиватель, который реагирует на событие. Это находится на контроллере просмотра A:

bLevelController.BLevelSelected += (object sender, BLevelController.BLevelSelectedEventArgs e) => {
    System.Diagnostics.Debug.WriteLine(e.bLevel.bLevelName);
};

bLevelController - это экземпляр моего контроллера B. Вы можете получить доступ к определенному событию, как показано выше, но вы должны знать, что используете имя класса (BLevelController) для доступа к BLevelSelectedEventArgs.

Было бы неплохо, если бы вы могли добавить другие возможности для передачи данных между контроллерами представлений (Notification Center, Protocol/Delegates,...).


делегат

Используется метод делегата. Часть 5 - Работа с таблицами в iOS Designer. Вы определяете делегата в своем UITableViewController:

public MasterViewController Delegate {get;set;} // will be used to Save, Delete later

Когда вы создаете экземпляр DetailViewController в MasterViewController, вы устанавливаете свойство Delegate. Пример:

public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
    base.PrepareForSegue (segue, sender);

    var detailViewController = segue.DestinationViewController as DetailViewController;

    if (detailViewController != null) {
        detailViewController.Delegate = this;
    }
}

В DetailViewController вы можете вызвать любой метод из MasterViewController:

public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
    {
    tableView.DeselectRow (indexPath, true); // iOS convention is to remove the highlight
    if (this.controller.Delegate != null) {
        this.controller.Delegate.SetItems (this.controller.items[indexPath.Row]);
    }
}

// a method in MasterViewController
public void SetItems(string items){
    this.items = items;
    this.NavigationController.PopViewControllerAnimated (true);
    // do something here
}

Это работает, потому что я передаю DetailViewController в DetailViewSource:

// in ViewDidLoad of DetailViewController
this.TableView.Source = new DetailViewSource (this);

// in the constructor of DetailViewSource
private CostCentreController controller;

public CostCentreListSource (CostCentreController controller)
{
    this.controller = controller;
}

NSNotificationCenter

Моя информация основана на xamarin/monotouch-samples и Xamarin NSNotificatioCenter: Как я могу передать NSObject? ,

Простой пример без передачи данных:

// class level variable
NSObject observer;

// register as observer
public override void ViewWillAppear (bool animated)
{
    base.ViewWillAppear (animated);
    observer = NSNotificationCenter.DefaultCenter.AddObserver ((NSString)UIDevice.OrientationDidChangeNotification, OrientationChanged);
}

// deregister as observer
public override void ViewDidDisappear (bool animated)
{
    base.ViewDidDisappear (animated);
    if (observer != null) { 
        NSNotificationCenter.DefaultCenter.RemoveObserver (observer);
        observer = null;
    }
}

// function which should do something when notification is received
public void OrientationChanged(NSNotification notification){
    Console.WriteLine ("test");
    // perhaps you can do the following as in the linked SO question: NSObject myObject = notification.Object;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню