如何在 Xamarin.ios 中调用另一个视图控制器中的函数?
How to call a function in an another view controller in Xamarin.ios?
我有一个名为 LeftViewController
的控制器,代表我的主控制器 ViewController
的侧边菜单。我希望当我单击侧边菜单中的按钮时调用主 ViewController 中的函数并更改按钮的标题。我试图在 ViewController.cs
中定义一个 class refresh_all
来负责更新我的按钮的标题,然后我会从那里定义一个 object 从 ViewController
到从中调用函数。
public class refresh_all{
ViewController v1 = new ViewController();
public void refresh_components()
{
v1.refresh_ac(); //
}
}
ViewController
class中的函数:
public void refresh_ac()
{
s2.SetTitle(CommonClass.value.ToString(), UIControlState.Normal);//s2 is my button name
}
我在 LeftViewController
控制器中从 refresh_all
class 定义了一个 object 如下:
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
非常感谢您的帮助。
能否请您检查一下 s2 按钮对象和 CommonClass 对象。 "CommonClass.value"这里的CommonClass应该是class的一个instance/object来调用属性。
发送左边的ViewController对象ViewController然后发送到refresh_allclass.
活动
我设法使事件方法正常工作。我的信息基于以下链接:
- PresentViewController and pass data back
- Communicate Between Master and Detail Controllers
- A better UITableViewSource in Xamarin iOS
- Event Handling UITableViewSource for iOS with Monotouch
在我的 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
class 中,我还定义了 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 的实例。您可以访问定义的事件,如上所示,但您必须知道您使用 class 名称(BLevelController
) 访问 BLevelSelectedEventArgs
.
如果您还可以添加其他可能性以在视图控制器(通知中心、Protocol/Delegates、...)之间传递数据,那就太好了。
代表
使用了一种委托方法Part 5 - Working with Tables in the iOS Designer。您在 UITableViewController
:
中定义了一个 Delegate
public MasterViewController Delegate {get;set;} // will be used to Save, Delete later
当您在 MasterViewController 中实例化 DetailViewController 时,您设置 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 and Xamarin NSNotificatioCenter: How can I get the NSObject being passed?。
没有数据传输的简单示例:
// 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;
}
引用 here
我有一个名为 LeftViewController
的控制器,代表我的主控制器 ViewController
的侧边菜单。我希望当我单击侧边菜单中的按钮时调用主 ViewController 中的函数并更改按钮的标题。我试图在 ViewController.cs
中定义一个 class refresh_all
来负责更新我的按钮的标题,然后我会从那里定义一个 object 从 ViewController
到从中调用函数。
public class refresh_all{
ViewController v1 = new ViewController();
public void refresh_components()
{
v1.refresh_ac(); //
}
}
ViewController
class中的函数:
public void refresh_ac()
{
s2.SetTitle(CommonClass.value.ToString(), UIControlState.Normal);//s2 is my button name
}
我在 LeftViewController
控制器中从 refresh_all
class 定义了一个 object 如下:
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
非常感谢您的帮助。
能否请您检查一下 s2 按钮对象和 CommonClass 对象。 "CommonClass.value"这里的CommonClass应该是class的一个instance/object来调用属性。
发送左边的ViewController对象ViewController然后发送到refresh_allclass.
活动
我设法使事件方法正常工作。我的信息基于以下链接:
- PresentViewController and pass data back
- Communicate Between Master and Detail Controllers
- A better UITableViewSource in Xamarin iOS
- Event Handling UITableViewSource for iOS with Monotouch
在我的 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
class 中,我还定义了 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 的实例。您可以访问定义的事件,如上所示,但您必须知道您使用 class 名称(BLevelController
) 访问 BLevelSelectedEventArgs
.
如果您还可以添加其他可能性以在视图控制器(通知中心、Protocol/Delegates、...)之间传递数据,那就太好了。
代表
使用了一种委托方法Part 5 - Working with Tables in the iOS Designer。您在 UITableViewController
:
public MasterViewController Delegate {get;set;} // will be used to Save, Delete later
当您在 MasterViewController 中实例化 DetailViewController 时,您设置 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 and Xamarin NSNotificatioCenter: How can I get the NSObject being passed?。
没有数据传输的简单示例:
// 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;
}
引用 here