Unable to load ViewController from tableview RowSelected in xamarin - c#

On selected tableview rowselected loading a DetailViewcontroller class.
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
if (OnRowSelected != null) {
OnRowSelected (this, new RowSelectedEventArgs (tableView, indexPath));
}
var detailController = new DetailViewController ();
UINavigationController controller = new UINavigationController();
controller.PushViewController(detailController, true);
}
Unable to load the DetailViewController.
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
method is in UITableViewSource
Is there any way to load DetailViewController on rowSelected.

When you create your table, you need to place it within the context of a Navigation controller.
UINavigationController nav = new UINavigationController(myTableViewController);
Then, when you want to display your DetailViewController, you can push it onto the already existing Navigation controller. However, by default your TableSource does not have access to NavigationController - you will need to pass a reference to your TableView controller when you create the TableSource so that the TableSource can access the NavigationController:
// in your controller, when you assign the source
this.TableView.Source = new MyTableViewSource(this);
// in your source, keep a class level ref to the parent
MyTableViewController _parent;
// your Source's constructor
public MyTableViewSource(MyTableViewController parent) {
_parent = parent;
}
// finally, in your RowSelected use the _parent reference to access the Nav controller
var detailController = new DetailViewController ();
_parent.NavigationController.PushViewController(detailController, true);

Related

UITableviewCell GetCell is not being called

I am using Visual Studio Community 2017 for Mac. I have a UITableview named SchoolSchedule. I am setting the Source from a button, but then when I click the button GetCell is not called, however, RowsInSection is called.
Here is my class:
public class ScheduleTableViewSource : UITableViewSource
{
private Schedule[] school;
public ScheduleTableViewSource(Schedule[] school)
{
this.school = school;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = (ScheduleCell) tableView.DequeueReusableCell("cell_id", indexPath);
var school1 = school[indexPath.Row];
cell.Updatecell(school1);
cell.TextLabel.Text = school[indexPath.Row].Site;
return cell;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return school.Length;
}
}
here is my button code :
partial void Get_button_TouchUpInside(UIButton sender)
{
bool check = NetworkInterface.GetIsNetworkAvailable();
if(check)
{
Service1 client = new Service1();
var school = client.CypressRidge("CypressRidge");
SchoolSchedule.Source = new ScheduleTableViewSource(school);
SchoolSchedule.ReloadData();
}
else{
Console.Write("Error no Internet connection");
return;
}
// int stop =0;
}
I have checked and there is data coming in from my service. so that is not the problem. can anyone help?
I had to deleted the table and make a new one.
there a bug in Xamarin.
I had the same problem and I managed to fix it setting up Identifier property of TableView first prototype row - in storyboard
In addition to implementing the IUITableViewDelegate and IUITableViewDataSource interfaces in the .cs file, calling RegisterNibForCellReuse, and assigning the table view's EstimatedRowHeight, it's easy to forget to set the data source and delegate properties of the table view in the XIB.

C#(Xamarin iOS) How to navigate from UITableView to other ViewController?

What line of code should I put inside of RowSelected?
I already used this but no luck at all :/ .
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}
mainnearmisses myTarget = (UIViewController)vc.Storyboard.InstantiateViewController("mnearm") as mainnearmisses;
myTarget.email = locations[indexPath.Row].shopname + "";
vc.PresentViewController(myTarget, true, null);
}
Some suggestions for you.
1. Set the ViewController itself as parameter in the initializing constructor of the dataSource.
in ViewController
this.TableView.Source = new TableSource(tableItems.ToArray(), this);
in dataSource
ViewController owner;
public TableSource (string[] items, ViewController owner)
{
tableItems = items;
this.owner = owner;
}
this can make your code easy to navigation to another VC.
just use this instead of looking for current vc on Windows .
this.owner.PresentViewController(myTarget, true, null);
2. If your tableView fills with the screen , you can change your ViewController to UITableViewController.
since it inherits form IUITableViewDataSource , so it can handle the event(i.e. that method create the tableView) in its own class.
3.As I mentioned above ,check if that viewController exists
check the storyboard id and find the corresponding viewController in your project.

Monotouch UIPickerView ValueChange Event for ViewController

I want to get event in case UIPickerView changes value in any of its component, so that my UIViewController can make changes to Labels. I have come across only one helpful method provided by PickerView model:
public override void Selected(UIPickerView pickerView, nint row, nint component)
When anything changes, there are corresponding changes reflected in model. But what should I do in case I want to reflect those changes back to ViewController? I want to do the job exactly like Delegates do in iOS. I am not much familiar with c#. Any help appreciated. Thanks.
public partial class ViewController : UIViewController
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
setupHandlers();
}
void setupHandlers()
{
pickerModel = new UnitPickerViewModel();
pickerModel.Items = lengthArray;
pickerModel.setDataForSecondComponent(lengthArray2);
pickerView = new UIPickerView();
pickerView.BackgroundColor = UIColor.LightGray;
pickerView.DataSource = pickerModel;
}
}
You can create weak and strong Obj-C style Delegates:
Strong Delegate:
Create a nested UIPickerViewDelegate class within your UIViewController class:
class PickerDelegate : UIPickerViewDelegate
{
public override void Selected(UIPickerView pickerView, nint row, nint component)
{
base.Selected(pickerView, row, component);
Console.WriteLine(row.ToString());
}
}
Create and assign the delegate to your UIPickerView:
var picker = new UIPickerView(UIScreen.MainScreen.Bounds);
picker.DataSource = this;
picker.Delegate = new PickerDelegate();
Weak Delegate:
Skip the nested class and add the UIPicker selected method to your UIViewController and tag it with a Foundation.Export:
[Export("pickerView:didSelectRow:inComponent:")]
public void Selected(UIPickerView pickerView, nint row, nint component)
{
Console.WriteLine(row.ToString());
}
Assign your UIViewController as the weak delegate:
var picker = new UIPickerView(UIScreen.MainScreen.Bounds);
picker.DataSource = this;
picker.WeakDelegate = this;
Add(picker);

In xamarin iOS - get [indexPath.Row] in UITableViewCell, Using button click event

In Xamarin iOS - I have a class named TableCell ( public class TableCell : UITableViewCell { } ) - in this class I have declared buttons.
In button click event , i'm trying to access [indexPath.Row] in UITableViewCell. I can select a row to find [indexPath.Row] in UITableViewSource.
public class TableSource : UITableViewSource {
// - - - -
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
new UIAlertView("Row Selected", tableItems[indexPath.Row], null, "OK", null).Show();
tableView.DeselectRow (indexPath, true); // iOS convention is to remove the highlight
}
// - - - -
}
How can I get [indexPath.Row] in UITableViewCell, Using button click event ..?
It's not the best approach but it will definitely work:
I would extend TableCell class with a new property:
public NSIndexPath IndexPath { get; set; }
Then I would add this line to the UITableViewSource's GetCell method if you are using the cell reusing pattern:
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
TableCell cell = tableView.DequeueReusableCell("YourIdentifier") ?? new TableCell();
cell.IndexPath = indexPath;
return cell;
}
And after that you could access the cell's current IndexPath anywhere. i.e.:
public TableCell()
{
UIButton btn = new UIButton(UIButtonType.RoundRect);
btn.TouchUpInside += (sender, args)
{
new UIAlertView("Button pressed!", indexPath.Row, null, "OK", null).Show();
}
}
Use VisibleCells property.
As soon as user selected row, the UITableViewCell will be visible.
Alternative solution (if you want to get similar, but not the same cell):
You can get it via UITableViewCell.GetCell using passed UITableView tableView, then cast it into your type of UITableViewCell, then call it's method using passed NSIndexPath indexPath.
Something like this:
public class TableSource : UITableViewSource {
// - - - -
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.GetCell(tableView, indexPath);
var myCell class = cell as MyCellClass;
if (myCell != null) {
// TODO: do something with cell.
}
}
// - - - -
}
// - - - -
}

Load. XIB in a class

How do I load a. XIB by clicking on the row of table view?
This example below is part of a class, as I fario alert the loading of this class?
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
tableView.DeselectRow (indexPath, true);
//this.PresentModalViewController(home,true);
}
There's not many details in your question and comments...
If you override the RowSelected method then you're likely inheriting a new type from UITableViewSource right ? If so then you should make its constructor keep a reference to the UITableViewController and use this reference to call PresentModalViewController later.
E.g.
public class MyTableViewSource : UITableViewSource {
UITableViewController ctrl;
public MyTableViewSource (UITableViewController c)
{
ctrl = c;
}
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
tableView.DeselectRow (indexPath, true);
var home = new UIViewController ("YouNibName", null); // default bundle
ctrl.PresentModalViewController (home, true);
}
}
note: I used UIViewController but you likely already have a type defined for your NIB.

Categories

Resources