如何在 MVVMCross 中测试 'first assignment' 绑定

How to test 'first assignment' of binding in MVVMCross

我有一个自定义 MvxConvertingTargetBinding,它对绑定的 UIView 的可见性执行动画(淡出 in/fade)。我在 UITableViewCell 上的某些按钮上使用此绑定。目的是用户点击按钮,模式中的一些规则发生变化,按钮消失(另一个按钮出现在它的位置)。

在将绑定值分配给控件期间,绑定会捕获 - 无论这是否是 'first time' 已应用绑定。如果是第一次,那么我不会为可见性设置动画。这很好用,因为我不想看到我的 table 单元格出现在网格中,然后让它们的所有按钮淡入 - 绑定上的要点是在用户期间底层模型发生变化时淡化按钮-相互作用... 这很好用。

当我的 Cell 被 TableViewSource 're-used' 时,问题就出现了。绑定被重新使用,它不再被视为 'first time' - 所以按钮得到动画。当您在列表中上下滚动时,这会产生这样的效果,所有按钮在滚动到视图中时都是 'fading in'...如您所想,它看起来很糟糕。

我怎样才能干净利落地解决这个问题?

我想在 TableViewSource 中放置一些代码,以测试重用,然后在重用的单元格上,访问绑定集,并尝试 'reset' 所有绑定...但是无法从 MvxFluentBindingDescriptionSet 定义访问绑定集合。

有什么想法吗?

谢谢

好的 - 我拼凑了一个解决方案...

不过,如果有人知道本机 MVVMCross 解决方案,请随时提供更好的答案。

值得庆幸的是,MVVMCross 在其生命周期结束时将 NULL 分配给 MvxTableViewCell.DataContext - 因此我可以使用它来指示单元格绑定应该是 'reset'。我还解决了无法通过使用静态 属性 访问绑定集中的目标绑定列表的问题(我知道有点恶心,但是嘿,当你看代码时很明显发生了什么 - 这UI 对单元测试来说仍然不是什么大问题。)

思路是这样的(伪代码):

MyMvxConvertingTargetBinding.SetValueImpl:
  if 'is_first_time' then 
    // don't animate the first-time binding of a view. Simple.
    set view value, clear 'is_first_time' and return.
  if 'ISRESETTING' then 
    // this is to ensure the View has the correct value, 
    // but is not animated when the table-view-cell is 
    // being removed from the table. It also resets the first-time state
    // so that when a new DataContext is assigned, it will perform
    // clean 'first-time' behavior.
    reset 'is_first_time' to TRUE, set view value, and return
  if is_first_time 
    then set view value and return
  otherwise, animate setting of view value

MvxTableViewCell.DataContext.Set:
  if current DataContext is not null and new DataContext is null:
    // This allows the TargetBinding to capture the fact that
    // the source data-model is being disconnected
    static MyMvxConvertingTargetBinding.ISRESETTING = TRUE
  Assign base.DataContext
  finally static MyMvxConvertingTargetBinding.ISRESETTING = FALSE

最后,当你使用你的特殊 'animated bindings' 之一时,这个想法将出现在任何 MvxTableViewCell 中,确保你覆盖 DataContext 并包装 'base.set;在 try/catch 中切换 'ISRESETTING',就像在伪代码中一样。这很好用。

这实际上解决的另一个问题是,当单元格被重新使用时,重新使用的 table-view-cell 仍在将子视图动画化为 'hiddden' 状态,并因此重新动画化为 'visible' 状态。这会导致动画冲突,可能会导致单元格出现在 table 中,而它的子视图在应该可见时被隐藏了!

如果有一项服务允许 MvxTargetBinding 捕获模型的 DataContext 中与给定绑定相关的更改,那就太好了。那么我们就不需要这里使用的静态字段方法了。