Monotouch UIPickerView ValueChange Event for ViewController - c#

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);

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.

Xamarin Forms - How to create custom render to give TableSection the default iOS Footer?

I want to add the default iOS footer to the tablesection in the tableview in Xamarin Forms. How can I go about doing this? I assume a customer renderer but I'm only reading that this can be done for Tableview?
To show an example, the following image is from Xcode storyboards when I enter the footer text on a static cell.
A Custom renderer is right, but you will have to use a custom renderer for the entire TableView. From there, you will need to override the TableViewModelRenderer and then the GetViewForFooter method in that ModelRenderer. Here's something that might help get you started:
public class FooterTableViewRenderer : TableViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
{
base.OnElementChanged(e);
if (Control == null)
return;
var tableView = Control as UITableView;
var formsTableView = Element as TableView;
tableView.WeakDelegate = new CustomFooterTableViewModelRenderer (formsTableView);
}
private class CustomFooterTableViewModelRenderer : TableViewModelRenderer
{
public CustomFooterTableViewModelRenderer(TableView model) : base(model)
{
}
public override UIView GetViewForFooter(UITableView tableView, nint section)
{
return new UILabel()
{
Text = TitleForFooter(tableView, section), // or use some other text here
TextAlignment = UITextAlignment.Center
};
}
}
}
As mentioned in my comments below, you can alternatively override other methods in your TableViewModelRenderer:
public override nfloat GetHeightForFooter(UITableView tableView, nint section)
{
return 10;
}
public override string TitleForFooter(UITableView tableView, nint section)
{
return "This is the title for this given section";
}

Mvvmcross - GetOrCreateCellFor of TableViewsource is never called

I am trying to set binding between my viewmodel and tableviewsource. But method GetOrCreateCellFor in tableviewsource is never called.
Here is my code:
ViewController:
public partial class MainView : MvxViewController
{
public MainView() : base("MainView", null)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
var source = new TableViewDataSource(FloorTableView);
this.CreateBinding(source).To((MainViewModel vm) => vm.Floors).Apply();
FloorTableView.Source = source;
FloorTableView.ReloadData();
}
}
ViewModel:
public class MainViewModel : MvxViewModel
{
DataService DataService;
ObservableCollection<Category> _Floors = new ObservableCollection<Category>();
public ObservableCollection<Category> Floors
{
get
{
LoadFloors();
return _Floors;
}
set
{
_Floors = value; RaisePropertyChanged(() => Floors);
}
}
void LoadFloors()
{
_Floors.Add(new Category {
Name = "Test"
});
}
}
TableViewSource:
public class TableViewDataSource : MvxTableViewSource
{
private static string CellId = "FloorCell";
public TableViewDataSource(UITableView tableView) : base(tableView)
{
tableView.RegisterNibForCellReuse(FloorCell.Nib, CellId);
}
public override System.nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
return 50;
}
protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
{
//this method never called
return tableView.DequeueReusableCell(CellId, indexPath);
}
}
FloorCell is simple empty tableview cell which extends MvxTableViewCell.
Where is the problem?
You need to implement the RowsInSection method otherwise the method won't get called.
You also need to make sure that the UITableView actually has a Frame set up either one you set yourself or through auto layout constraints. If the height or width is 0 the method won't get called either.
This might also happen if height of your table view is lower than at least on item including footer / header size. So be sure you calculate height appropriately (with one item available it will add scrolling to your table view, but GetOrCreateCell will be called).

Unable to load ViewController from tableview RowSelected in xamarin

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);

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