MvvmCross binding with NSTableView

Multi tool use
MvvmCross binding with NSTableView
After searching multiple blogs and videos I find that to implement the UITableView
one can use MvxTableViewController
, but what to use for NSTableView
?
UITableView
MvxTableViewController
NSTableView
I do not find any tutorial, example that covers OSX binding TableView using MvvmCross. Any leads will be appreciated.
1 Answer
1
We don't have MvxTableViewController
for macOS.
MvxTableViewController
However, if you abstract from that, binding to a NSTableView
is very similar to a UITableView
on iOS.
NSTableView
UITableView
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.
Items
ItemsSource
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.
Text
Name
Items
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.
MvxTableViewSource
GetOrCreateViewFor
MvxTableCellView
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:
MvxTableViewSource
MyTableSource
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
.
Name
Url
Items
ItemsSource
tableView
//bind table view var source = new MvxTableViewSource(tableView); tableView.Source = source; set.Bind(source).For(v => v.ItemsSource).To(vm => vm.Items);
But how to bind the contents of the table view?
– Anoop Vaidya
Jul 2 at 11:07
I will elaborate :)
– Cheesebaron
Jul 2 at 11:23
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thanks for the answer, I did some changes and I am getting rows (not with correct data, that I will figure out). I have
tableView
as an outlet and modified some parts as://bind table view var source = new MvxTableViewSource(tableView); tableView.Source = source; set.Bind(source).For(v => v.ItemsSource).To(vm => vm.Items);
– Anoop Vaidya
Jul 2 at 9:06