MvvmCross связывание с NSTableView - PullRequest
0 голосов
/ 02 июля 2018

После поиска по нескольким блогам и видео я обнаружил, что для реализации UITableView можно использовать MvxTableViewController, но что использовать для NSTableView?

Я не нахожу учебник, пример, который охватывает привязку OSX TableView с использованием MvvmCross. Любые выводы будут оценены.

1 Ответ

0 голосов
/ 02 июля 2018

У нас нет MvxTableViewController для macOS.

Однако, если абстрагироваться от этого, привязка к NSTableView очень похожа на UITableView в 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();
}

Это свяжет ViewModel Items с ItemsSource. Однако вам все равно нужно будет указать, что связывать в ячейке. Самый простой способ сделать это - предоставить TableColumn.

var column = new MvxTableColumn();
column.Identifier = "First";
column.BindingText = "Text Name";
column.HeaderCell = new NSCell("Example");
_tableView.AddColumn(column);

Это свяжет свойство Text TableColumn с Name в элементах, предоставленных в Items в ViewModel.

Если вам нужно больше этого, вам нужно будет создать подкласс 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);
        }
    }
}

И таблица источника:

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

Затем вместо использования MvxTableViewSource в первом примере используйте вместо него MyTableSource:

var source = new MyTableViewSource(_tableView, "Text Name; ImageUrl Url");
_tableView.Source = source;

Где Name и Url находятся в Элементе в Items, связанном с ItemsSource.

...