Binding to TableView Xamarin - xamarin.ios

I am trying to use the following to bind to a TableView using Xamarin ios but i not having much luck As you can see I am using parse.com as me datalyer
var query = from gaemPlayer in ParseObject.GetQuery ("players")
select gaemPlayer;
myPlayers.DataSource = query;
Where myPlayers is the table source Name i gave in iOS designer is c# I would normally have the ToList function to create a generic list is that not he case with Xamarin.

Your source needs to be a class derived from UITableViewSource. The source class will have methods to determine how many sections and rows per section are in a table, as well as method to actually build a UITableViewCell to display. There are other methods you can override for additional functionality, but those are the bare minimum.
Note that the reason you can't just use a List as a Source is because Xamarin is modeling the Obj-C UITableView pattern. An alternative for building simple tables is to use MonoTouch.Dialog.
public class MySource : UITableViewSource
{
private List<item> data;
public MySource(List<Item> data) {
this.data = data;
}
public override int RowsInSection (UITableView tableview, int section)
{
return data.Count();
}
public override int NumberOfSections (UITableView tableView)
{
return 1;
}
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
// instantiate and return your UITableViewCell here
}

Related

Why is the ConvertBack method of an MvvmCross Value Converter not being called?

First time using MvvmCross Value Convertors. I've created a value convertor to handle data manipulation between a bool? element in my view and a bool property in my view model.
public sealed class NullableBooleanValueConverter : MvxValueConverter<bool, bool?>
{
// ViewModel -> View
protected override bool? Convert(bool value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (bool?)value;
}
// View -> ViewModel
protected override bool ConvertBack(bool? value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value ?? false;
}
}
And I've bound my view element to the view model when in my view's ViewDidLoad.
var set = this.CreateBindingSet<SettingsView, SettingsViewModel>();
set.Bind(wifiOnlyElement).For(View => View.BooleanValue).To(ViewModel => ViewModel.ConnectOnWifiOnly).WithConversion("NullableBoolean").TwoWay();
set.Apply();
Note: I added the .TwoWay() binding modifier to the set.Bind, thinking the mode might have to be explicitly stated, with no change.
When the view appears the Convert method of NullableBooleanValueConverter is called.
However, when the view is closed, the corresponding ConvertBack method is not called.
Based on this question I suspect that I'm not binding to the correct property. The screen control that I'm creating the binding on is a custom UITableViewCell descended from Xamarin's Dialog/Element classes and the nullable BooleanValue on this screen control is public and that's where the true/false value is stored when the element is tapped.
BooleanValue is a public property on a Dialog/Element class called CheckboxElement that inherits from the base Element class.
NSObject
|_ Element
|_ CheckboxElement
.BooleanValue
There is an overridden property in CheckboxElement called Selected that changes the value of BooleanValue when the element is tapped.
public override void Selected(DialogViewController dvc, UITableView tableView, NSIndexPath indexPath)
{
BooleanValue = !BooleanValue;
...
}
Selected is called by the DialogViewController's RowSelected method.
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
Container.Selected(indexPath);
}
Which calls the DialogViewController's Selected method (element is the CheckboxElement).
public virtual void Selected(NSIndexPath indexPath)
{
var section = Root.Sections[indexPath.Section];
var element = section.Elements[indexPath.Row];
ActiveElement = element;
element.Selected(this, Root.TableView, indexPath);
}
Doesn't look like there's anything there that's interfering.
Let me know if you need more info. Thanks in advance.
Mvvmcross relies on event notifications to tell it when values have changed.
When event notifications aren't available, then you can write custom bindings to help MvvmCross know when the ui has updated. For more on this, see n=28 - custom,bindings in http://mvvmcross.blogspot.com
For the specific case of Monotouch.Dialog, Mvvmcross provides its own branch which includes two-way bindings for boolean elements such as UiSwitch-based Elements. You may find it easier to use this mvvmcross branch - for more on this, look for dialog in the n+1 videos.

Xamarin.ios initialize UIView

I am using Xamarin.iOS. I have created UIView with a few UITextFields. I am looking for best way to initialize text value in these textfields from code.
I can pass text data in the constructor of UIViewContoller, but I don't have access to textFields inside it (they are null). I can change text value of textFields in viewDidLoad method.
I don't want to create additional fields in controller class to store data passed by constructor and use them in viewDidLoad. Do you know better solution ?
I don't want to create additional fields in controller class to store
data passed by constructor and use them in viewDidLoad.
But that's how it's meant to be done.
Alternatively, you can create less fields/properties in your viewcontroller if you use a MVVM pattern:
public class UserViewModel {
public string Name { get; set;}
public string Title { get; set;}
}
public class UserViewController : UIViewController
{
UserViewModel viewModel;
public UserViewController (UserViewModel viewModel) : base (...)
{
this.viewModel = viewModel;
}
public override void ViewDidLoad ()
{
userName.Text = viewModel.Name;
userTitle.Text = viewModel.Title;
}
}
That's the kind of pattern which gives you a lot of code reuse accross platforms (android, WP, ...) and clearly separate concerns. It's a (very) little bit of extra code, but it's worth every byte.

Not able to use Custom XIB outlets with UICollectionViewCell

When accessing to outlets from my CustomClass : UICollectionViewCell, they are appearing as not initialized and can not set a proper value.
Every example I've seen it uses a plain Class (no XIB) to set the UI.
[Register("CustomCommentCell")]
public partial class CustomCommentCell : UICollectionViewCell
{
public static readonly NSString Identifier = new NSString("CustomCommentCell");
public CustomCommentCell () : base()
{
}
public CustomCommentCell (IntPtr handle) : base (handle)
{
}
public void updateData()
{
this.lblComment.Text = "Test";
}
}
On the other hand, I have registered the Class:
this.tableComments.RegisterClassForCell (typeof(CustomCommentCell),commentCellId);
and have the GetCell properly set.
However, when trying to set the outlets to a specific value, it indicates it is null. (this.lblcomment = null) while it should have been a UILabel initialized.
Any clues?
to create the Custom CollectionViewCell using XIB. do the following
1) create C# class which inherits from UIcollectionViewCell
[Register("MyCustomCell")]
public class MyCustomCell : UICollectionViewCell
{
public static readonly NSString Key = new NSString ("MyCustomCell");
[Export ("initWithFrame:")]
public MyCustomCell(CoreGraphics.CGRect frame) : base (frame)
{
}
public override UIView ContentView {
get {
var arr= NSBundle.MainBundle.LoadNib ("MyCustomCell", this, null);
UIView view =arr.GetItem<UIView> (0);
view.Frame = base.ContentView.Frame;
base.ContentView.AddSubview (view);
return base.ContentView;
}
}
}
2) Add a IphoneView XIB file has the Same Name as that of Class created in step 1
3) Open XIB in XCODE and do the Following Changes
3.1)Select the FileOwner set the Class same name as Step 1
3.2)Select The View Set the Class name UIView
4) Design Your XIB Accordingly
I can't follow quite the problem you are seeing. What is a "Custom XIB outlet"? Why is this question tagged "custom-controls"? Is there some example code or pictures you can show to help explain the problem?
The approach I use for UICollectionViewCell's is the same as I use for UITableViewCell - see the tutorial - http://slodge.blogspot.co.uk/2013/01/uitableviewcell-using-xib-editor.html
Update: From the code you've posted as a comment (not sure if it's complete or not), I think it would be useful for you to follow through that tutorial. There are a few steps to complete including registering the custom class name and including using RegisterNibForCellReuse - one of those will probably fix this for you.

UICollectionView cell sizes

Stackoverflow question https://stackoverflow.com/a/13555814/1678391 was answered about setting variable sized cells in a UICollectionViewController. I'm trying to figure out how to do this with a UICollectionView object contained in a UIViewController. GetSizeForItem is what I need but don't see where to get it.
My implementation adds a UICollectionView to my UIViewController via Xcode. In my code I'm doing the following;
public partial class CustomViewController : UIViewController
{
public override void ViewDidLoad()
{
collectionView.RegisterClassForCell(typeof(MyCell), cellId);
}
public override void ViewWillAppear(bool animated)
{
collectionView.Source = new CollectionViewSource(items, cellId);
}
class CollectionViewSource : UICollectionViewSource
{
}
class MyCell : UICollectionViewCell
{
}
}
According to http://docs.go-mono.com GetSizeForItem is available only for UICollectionViewDelegateFlowLayout class.
To use that method you should implement UICollectionViewDelegateFlowLayout subclass and assing it to Delegate property of UICollectionViewController. Example.

monotouch UITableViewDelegate RowSelected event cannot be used?

I am using a custom UITableViewDelegate and in my controller I want to run some code when the tableview has a rowselected. I noticed the UITableViewDelegate already has an event called RowSelected but you cannot use it I'm guessing because there is a method in UITableViewDelegate with the exact same name.
If I write:
mytableviewdelegate.RowSelected += myeventhandler;
This will not compile and gives the error:
"Cannot assign to 'RowSelected' because it is a 'method group'"
Any ideas, I have a work around which is fine so Im really looking at working out if this is a bug in MonoTouch?
How are you implementing the custom UITableViewDelegate? I would suggest using Monotouch's UITableViewSource as it combines both the UITableViewDataSource and the UITableViewDelegate into one file which makes things so much easier.
Some example code:
(in your UIViewController that contains the UITableView)
tableView.Source = new CustomTableSource();
Then you'll want to create a new class for this:
public class CustomTableSource : UITableViewSource
{
public CustomTableSource()
{
// constructor
}
// Before you were assigning methods to the delegate/datasource using += but
// in here you'll want to do the following:
public override int RowsInSection (UITableView tableView, int section)
{
// you'll want to return the amount of rows you're expecting
return rowsInt;
}
// you will also need to override the GetCells method as a minimum.
// override any other methods you've used in the Delegate/Datasource
// the one you're looking for in particular is as follows:
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
// do what you need to here when a row is selected!
}
}
That should help you get started. In the UITableViewSource class you can always type public override and MonoDevelop will show you what methods are available to be overriden.

Resources