Reputation: 46563
After searching multiple blogs and videos I find that to implement the UITableView
one can use MvxTableViewController
, but what to use for NSTableView
?
I do not find any tutorial, example that covers OSX binding TableView using MvvmCross. Any leads will be appreciated.
Upvotes: 2
Views: 205
Reputation: 24470
We don't have MvxTableViewController
for macOS.
However, if you abstract from that, binding to a NSTableView
is very similar to a UITableView
on iOS.
private NSTableView _tableView;
public override void ViewDidLoad()
{
base.ViewDidLoad();
_tableView = new NSTableView();
// add constraints or size otherwise
var source = new MvxTableViewSource(_tableView);
_tableView.Source = source;
var set = this.CreateBindingSet<MyViewController, MyViewModel>();
set.Bind(source).For(v => v.ItemsSource).To(vm => vm.Items);
set.Apply();
}
This will bind the ViewModel Items
to the ItemsSource
. However, you will still need to specify what to bind in the cell. The simplest way to do this is to provide a TableColumn.
var column = new MvxTableColumn();
column.Identifier = "First";
column.BindingText = "Text Name";
column.HeaderCell = new NSCell("Example");
_tableView.AddColumn(column);
This will bind the Text
property of the TableColumn to Name
in the items provided in Items
in the ViewModel.
If you need more than this you will need to subclass MvxTableViewSource
and override GetOrCreateViewFor
and in there provide your own subclass of MvxTableCellView
where you do more. This could look something as follows.
public class MyCustomCell : MvxTableCellView
{
public MyCustomCell(IntPtr handle) : base(handle)
{
}
public MyCustomCell(string bindingText) : base(bindingText)
{
this.Frame = new CGRect(0, 0, 100, 50);
TextField = new NSTextField(new CGRect(50, 0, 100, 50))
{
Editable = false,
Bordered = false
};
ImageView = new NSImageView(new CGRect(0, 0, 50, 50));
AddSubview(TextField);
AddSubview(ImageView);
this.Initialize(bindingText);
}
private string _imageUrl;
public string ImageUrl
{
get => _imageUrl;
set
{
_imageUrl = value;
ImageService.Instance.LoadUrl(_imageUrl).Into(ImageView);
}
}
}
And the table source:
public class MyTableSource : MvxTableViewSource
{
private string _bindingText;
public MyTableSource(NSTableView tableView, string bindingText) : base(tableView)
{
_bindingText = bindingText;
}
public override NSView GetViewForItem(NSTableView tableView, NSTableColumn tableColumn, nint row)
{
if (ItemsSource == null)
return null;
var item = ItemsSource.ElementAt((int)row);
var view = new MyCustomCell(_bindingText);
if (view is IMvxDataConsumer bindable)
bindable.DataContext = item;
return view;
}
}
Then instead of using MvxTableViewSource
in the first example, use your own MyTableSource
instead:
var source = new MyTableViewSource(_tableView, "Text Name; ImageUrl Url");
_tableView.Source = source;
Where Name
and Url
are in the Item in the Items
bound to the ItemsSource
.
Upvotes: 4