MVVMCross:ClearBindings() - 如何在Touch中使用?

时间:2013-07-16 15:31:34

标签: xamarin.ios mvvmcross

ClearBindings()如何在MvvmCross中运作?

至于测试目的,我只是试图在ViewDidLoad()中为WeekSelectorView清除我的TableView的itemsSource。这是我尝试过的,但似乎没有任何效果。

(“this”指的是我当前的WeekSelectorView实例)

var source = new WeekSelectorTableSource(TableView, this);
TableView.Source = source;

var set = this.CreateBindingSet<WeekSelectorView, WeekSelectorViewModel>();
set.Bind(source).To(vm => vm.Options);
set.Apply();

//None of these work
this.ClearBindings (this);
this.ClearBindings (source);
this.ClearBindings (TableView.Source);
this.ClearBindings (source.ItemsSource);
this.ClearBindings ("ItemsSource");
this.ClearBindings ("source.ItemsSource");
this.ClearBindings ("TableView");
this.ClearBindings ("TableView.Source");
this.ClearBindings (TableView);
this.ClearBindings ("TableView.Source.ItemsSource");
this.ClearBindings (set);
this.ClearBindings ("set");
this.ClearBindings ("Options");

TableView.ReloadData();

目前,当我加载应用程序时,我的WeekSelectorView根据我的ViewModel数据加载表。我想清除绑定,所以根本不应该有任何表。

this.ClearAllBindings();

上面这行有效,但我不想清除所有绑定,我只想清除我的TableView的ItemsSource。


编辑:

我目前有一个与之关联的.xib的WeekSelectorView。在.xib中是一个TableView(以及其他用户控件)。

我的WeekSelectorView将源设置为我自己的类“WeekSelectorTableSource”。此tablesource类根据ItemsSource绑定确定行/节的数量。然后它在我的GetOrCreateCellsFor

中创建一些自定义.xib单元格
    protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
    {
        var weekSelectorCell = WeekSelectorCell.Create();

        var set = _WeekSelectorView.CreateBindingSet<WeekSelectorView, WeekSelectorViewModel>();

        //Using string bindings since bindings with an index doesn't work  
        //ex: vm => vm.Options[indexPath.Row].Title
        set.Bind(weekSelectorCell).For(wc => wc.Title).To(string.Format("{0}{1}{2}", Options, indexPath.Row, Title)).OneWay();
        set.Bind(weekSelectorCell).For(wc => wc.Date).To(string.Format("{0}{1}{2}", Options, indexPath.Row, DateString)).OneWay();
        set.Bind(weekSelectorCell).For(wc => wc.Hours).To(string.Format("{0}{1}{2}", Options, indexPath.Row, TotalHours)).WithConversion(new HoursDecimalToHoursMinutesConverter(), null).OneWay();
        set.Apply();

        return weekSelectorCell;
    }

现在我想要ClearBindings() ......

每次重新加载表格时,我以前的绑定都会持续存在。因此,如果我将每个3个细胞绑定4个细胞,那么我的应用程序第一次将有12个与细胞相关的绑定。一旦我重新加载表(仍然有4个单元格)将有24个绑定....然后36,48等。

这是诊断的一部分......

2013-07-16 16:26:03.950 FCXiOSv2[569:21e03] MvxBind: Warning: 1259.41 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
2013-07-16 16:26:03.951 FCXiOSv2[569:21e03] MvxBind: Diagnostic: 1259.41 Receiving setValue to Week
2013-07-16 16:26:03.952 FCXiOSv2[569:21e03] MvxBind: Warning: 1259.42 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
2013-07-16 16:26:03.953 FCXiOSv2[569:21e03] MvxBind: Diagnostic: 1259.42 Receiving setValue to 7/8/13 - 7/14/13
2013-07-16 16:26:03.954 FCXiOSv2[569:21e03] MvxBind: Warning: 1259.42 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set

我重新加载表后,我刚收到FLOODED这条消息,所以我希望每次TableView.ReloadData()之前都清除我的绑定。


编辑:

在考虑过并与使用Windows本机绑定的同事交谈之后,我发现有很多我做错的事情,长话短说,我不需要使用ClearBindings(view)

我让我的最外面的视图处理所有绑定,所以当一个视图被重新加载(也就是表中的单元格)时,绑定仍然存在,因为最外面的视图还没有被释放。因此,我的所有子视图都没有处理自己的绑定,这是一个重大错误。

要修改此更改(以我想象的'正确'方式),我的自定义单元格继承自MvxTableViewCell并添加了延迟绑定。

public WeekSelectorCell (IntPtr handle) : base (handle)
{
    this.DelayBind (() => 
    {
        var set = this.CreateBindingSet<WeekSelectorCell, WeekViewModel>();
        set.Bind(DateLabel).For(lbl => lbl.Text).To(vm => vm.DateString);
        set.Bind(HoursLabel).For (lbl => lbl.Text).To(vm => vm.TotalHours).WithConversion(new HoursDecimalToHoursMinutesConverter(), null);
        set.Bind(TitleLabel).For(lbl => lbl.Text).To(vm => vm.Title);
        set.Apply();
    });
}

我之前尝试过此操作,但尝试在<WeekSelectorCell, WeekSelectorViewModel>之间创建一个集并尝试访问(vm =&gt; vm.Options [ROW] .Date),但这总是失败。我终于知道我需要在<WeekSelectorCell, WeekViewModel>之间创建一个集合,因为Options[]ObservableCollection WeekViewModel

就像我说的,长话短说,我不需要使用ClearBindings(view)

1 个答案:

答案 0 :(得分:3)

  

ClearBindings()如何在MvvmCross中运行?

ClearBindings()ClearBindings(view)

每个MvxBindingContext维护3个单独的“绑定”列表:

  1. 直接在上下文中创建的绑定列表
  2. 在子视图中创建的绑定的基于视图的查找表 - 当父视图在父绑定上下文中动态膨胀时,这些绑定目前仅用于Android绑定。
  3. 等待第一次调用DataContext=value
  4. 的操作列表(通常会继续创建绑定)

    其中第一个目前是iOS中使用的主要内容 - MvxBindingContext为该列表公开的唯一公开明确API是ClearAll

    第二个仅在Android中用于某些子视图Xml通胀 - 并且ClearBindings(view)允许这些用于此。

    所有这些背后的历史尤其与Android和iOS内存管理的许多问题有关 - 特别是在尝试确保我们跟踪和处理所有绑定时,包括在子视图中,列表内创建的绑定等。


    如果我们可以在这里找出一个好的用例 - 稍微扩展一下“这仅用于某些测试目的” - 那么ClearBindingsForObjectEnumerateBinding API就可以了考虑用于扩展的绑定上下文API - 但它肯定需要更强的要求,以确保项目捕获了API真正有用的内容。

    与此同时,我猜你可以使用tableView创建并注册绑定作为查找,如果你想 - 例如类似的东西:

    var bindings = MvxBindingSingletonCache.Instance.Binder.Bind(BindingContext.DataContext, tableView, "ItemsSource MySource");
    this.RegisterBindingsFor(tableView, bindings);
    

    然后,您就可以拨打ClearBindings(tableView);


    或者,如果你想阻止个人绑定工作,那么你可以提前Dispose - 这将清除它的源绑定 - 例如如果你这样做:

        _myDisposableBindings = MvxBindingSingletonCache.Instance.Binder.Bind(BindingContext.DataContext, tableView, "ItemsSource MySource");
        this.AddBindings(_myDisposableBindings);
    
    然后你可以在某些时候做类似的事情:

        foreach (var binding in _myDisposableBindings)
        {
            binding.Dispose();
        }
        _myDisposableBindings = null;
    

    或者 - 也许这就是我要去的方式(虽然它取决于你的用例是什么) - 然后将你的表放在它自己的MvxView控件中可能更容易 - 这可以拥有它自己的BindingContext,你可以打电话给ClearAllBindings()

    有关MvxView的更多信息,请参阅http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html


    最后,我可能还会考虑确定您是否可以保持绑定,但可以清除ViewModel中的ItemsSource