我有一个自定义的 MvxConvertingTargetBinding,它在绑定的 UIView 的可见性上执行动画(淡入/淡出)。我在UITableViewCell上的某些按钮上使用此绑定。目的是用户点击按钮,模式中的某些规则更改,按钮消失(另一个按钮出现在其位置)。
绑定在将绑定值分配给控件期间捕获 - 无论这是否是"第一次"应用绑定。如果是第一次,那么我不会对可见性进行动画处理。这很好用,因为我不想看到我的表格单元格出现在网格中,然后让它们的所有按钮淡入 - 绑定上的要点是在用户交互期间基础模型更改时淡入按钮......这工作正常。
当我的单元格被 TableViewSource "重用"时,问题就出现了。绑定被重复使用,并且不再被视为"第一次" - 因此按钮会进行动画处理。这具有以下效果:当您在列表中上下滚动时,所有按钮在滚动到视图中时都会"淡入"......可以想象,它看起来很糟糕。
如何以干净的方式解决此问题?
我想过将一些代码放在 TableViewSource 中,以测试重用,然后在重用的单元格上,访问绑定集,并尝试"重置"所有绑定......但是无法从 MvxFluentBindingDescriptionSet 定义中访问绑定集合。
有什么想法吗?
谢谢
好的 - 我拼凑出了一个解决方案...
不过,如果有人知道本机 MVVMCross 解决方案的方法,请随时提供更好的答案。
值得庆幸的是,MVVMCross 在 MvxTableViewCell.DataContext 生命周期结束时将 NULL 分配给它 - 所以我可以使用它来指示单元格绑定应该"重置"。我还通过使用静态属性解决了无法访问绑定集中的目标绑定列表的问题(我知道有点恶心,但是嘿,当您查看代码时,这很明显发生了什么 - 这是 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
最后,当你使用一个特殊的"动画绑定"时,这个想法会在任何MvxTableViewCell中出现,确保你覆盖DataContext并将'base.set;包装在一个try/catch中,切换'ISRESET',就像在伪代码中一样。这很好用。
这实际上解决的另一个问题是,当单元格被重用时,重用的表视图单元格仍然将子视图动画化为"隐藏"状态,从而重新动画化为"可见"状态。这会导致动画冲突,这可能会导致单元格出现在表中,其子视图在应该可见时隐藏
!更好的服务是允许MvxTargetBinding 捕获与给定绑定相关的模型的 DataContext 中的更改。那么我们就不需要这里使用的静态场方法了。