如何在Xamarin.ios中的另一个视图控制器中调用函数?

时间:2020-11-05 10:43:40

标签: c# ios xamarin xamarin.ios event-handling

我有一个名为LeftViewController的控制器,它代表我的主控制器ViewController的侧面菜单。我想单击侧面菜单中的按钮以在主ViewController中调用函数并更改按钮的标题。我试图在refresh_all中定义一个类ViewController.cs来负责更新按钮的标题,然后从ViewController定义一个对象来从中调用函数。

 public  class refresh_all{


        ViewController v1 = new ViewController();

        public void refresh_components()
        {


            v1.refresh_ac(); //

        }

    }

ViewController类中的函数:

 public void refresh_ac()
        {
            s2.SetTitle(CommonClass.value.ToString(), UIControlState.Normal);//s2 is my button name
        }

我在refresh_all控制器的LeftViewController类中定义了一个对象,如下所示:

    partial void Conbtn_TouchUpInside(UIButton sender)
        {

            refresh_all r1 = new refresh_all();

            r1.refresh_components();

        }

我在s2.SetTitle(CommonClass.value.ToString(), UIControlState.Normal);上遇到错误 说Object reference not set to an instance of an object

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

能否请您检查s2按钮对象和CommonClass对象。 “ CommonClass.value”在这里,CommonClass应该是该类的实例/对象以调用属性。

在LeftViewController中发送ViewController对象,然后将其发送到refresh_all类。

答案 1 :(得分:0)

事件

我设法使事件处理生效。我的信息基于以下链接:

在我的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)来访问{{ 1}}。

如果您还可以添加其他可能性来在视图控制器之间传递数据(通知中心,协议/代表等),那将是很好的选择。


委托

Part 5 - Working with Tables in the iOS Designer使用了一种委托方法。您在BLevelSelectedEventArgs中定义一个 Delegate

UITableViewController

MasterViewController 中实例化 DetailViewController 时,设置 Delegate 属性。示例:

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

DetailViewController 中,您可以从 MasterViewController 调用任何方法:

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 传递给 DetailViewSource

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
}

NSNotificationCenter

我的信息基于xamarin/monotouch-samplesXamarin NSNotificatioCenter: How can I get the NSObject being passed?

没有数据传输的简单示例:

// 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;
}

引用here