如何将命令绑定到ios表节标题单击?

时间:2013-08-30 12:31:04

标签: ios xamarin.ios mvvmcross

如何绑定Command以接收表格中的部分?我使用MvxViewController和自定义TableSource,但似乎在为部分创建UIView时我无法为我的VM添加绑定。

这是我的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 个答案:

答案 0 :(得分:0)

有几种方法可以达到这种效果。

对于您当前的要求,实现它的最简单方法是只向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绑定

将此命令绑定到ViewModel
set.Bind(source)
   .For(s => s.FooCommand)
   .To(vm => vm.SectionTappedCommand)
   .OneWay();

如果你想进一步 - 如果你想做一个更复杂的绑定 - 那么你实际上可以为Header View设置一个完整的绑定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