如何在 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 中与给定绑定相关的更改,那就太好了。那么我们就不需要这里使用的静态字段方法了。
我有一个自定义 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 中与给定绑定相关的更改,那就太好了。那么我们就不需要这里使用的静态字段方法了。