Как привязать команду к щелчку заголовка раздела таблицы ios?

Как я могу связать команду, чтобы получать нажатия на разделы моей таблицы? Я использую MvxViewController с пользовательским TableSource, но кажется, что я не могу добавить привязки к моей виртуальной машине при создании UIView для разделов.

Вот моя ViewModel:

public class TestViewModel : MvxViewModel
{
    private ObservableCollection<string> _sections;
    public ObservableCollection<string> Sections
    {
        get { return _sections; }
        set { _sections = value; RaisePropertyChanged(() => Sections); }
    }


    private MvxCommand _sectionTappedCommand;
    public ICommand SectionTappedCommand
    {
        get
        {
            _sectionTappedCommand = _sectionTappedCommand ?? new MvxCommand(DoSectionTappedCommand);
            return _sectionTappedCommand;
        }
    }
    private void DoSectionTappedCommand()
    {
        //I want this command somehow to be called when user taps section header
        Debug.WriteLine("Section tapped!");        
    }
}

Мой взгляд:

[Register("TestView")]
public class OrderView : MvxViewController
{
    public override void ViewDidLoad()
    {
        View = new UIView() { BackgroundColor = UIColor.White };
        base.ViewDidLoad();

        var table = new UITableView(new RectangleF(0, 20, 320, 660));
        Add(table);

        var source = new TestTableSource(table);
        table.Source = source;

        var set = this.CreateBindingSet<OrderView, OrderViewModel>();
        // I think here I need to write something like:
        // set.Bind(source).For(s => s.Section.TapAction).To(vm => vm.SectionTappedCommand);**
        set.Bind(source).For(s => s.ItemsSource).To(vm => vm.Sections).OneWay();
        set.Apply();

    }
}

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

public class TestTableSource : MvxBaseTableViewSource
{
    // all needed overrides implemented
    private IList<OrderGuest> _sections;
    public IList<OrderGuest> ItemsSource
    {
        get
        {
            return _sections;
        }
        set
        {
            _sections = value;
            ReloadTableData();
        }
    }
    public override UIView GetViewForHeader(UITableView tableView, int section)
    {
        // Do I need to add bindings here?
        var view = new OrderGuestSectionHeader(OrderGuestSectionHeader(tableView, section), () => {
            Debug.WriteLine("selected " + section.ToString());
        });
        return view;
    }

    public override int NumberOfSections(UITableView tableView)
    {
        if (_sections == null)
            return 0;

        return _sections.Count;
    }

    public override string[] SectionIndexTitles(UITableView tableView)
    {
        if (_sections == null)
            return null;

        return _sections.Select(x => x.Name).ToArray();
    }

}

Подкласс UIView для заголовка раздела:

public sealed class OrderGuestSectionHeader : UIView
{
    private UIButton SectionButton;
    public Action TapAction;

    public OrderGuestSectionHeader(string header, Action tapped)
    {
        Frame = new RectangleF(0, 0, 320, 20);
        BackgroundColor = UIColor.Blue;
        SectionButton = new UIButton(this.Frame);
        SectionButton.TouchUpInside += SectionButton_TouchUpInside;
        SectionButton.Title(header);
        TapAction = tapped;
        Add(SectionButton);
    }

    private void SectionButton_TouchUpInside(object sender, EventArgs e)
    {
        TapAction();
    }
}

1 ответ

Решение

Есть несколько способов достичь этого эффекта.

Для ваших текущих требований самый простой способ достичь этого - добавить одну команду в TestTableSource и чтобы эта команда была передана заголовку вашего раздела в обработчике Action.

public class TestTableSource : MvxBaseTableViewSource
{
    public ICommand FooCommand { get; set; }

    // existing code

    public override UIView GetViewForHeader(UITableView tableView, int section)
    {
        var view = new OrderGuestSectionHeader(OrderGuestSectionHeader(tableView, section), () => {
            Debug.WriteLine("selected " + section.ToString());
            if (FooCommand != null) FooCommand.Execute(null);
        });
        return view;
    }
}

Затем эту команду можно привязать к модели представления, добавив OrderView связывание:

set.Bind(source)
   .For(s => s.FooCommand)
   .To(vm => vm.SectionTappedCommand)
   .OneWay();

Если вы хотите пойти дальше - если вы хотите сделать более сложное связывание - тогда вы действительно можете установить полное связывание DataContext для просмотра заголовка. Самый простой способ сделать это - наследовать от MvxView, Я не буду вдаваться в подробности этого здесь - вместо этого для введения в MvxViewсм. видео N+1 - http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html с примером исходного кода в https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-32-ViewModels

Другие вопросы по тегам