MvvmCross:为什么视图消失后绑定仍然存在?

时间:2013-08-06 15:55:15

标签: xamarin.ios mvvmcross

注意:

有很多代码/诊断,首先我讨论我的问题,然后是很多代码(帮助回答任何问题),最后我添加了3个不同的诊断块,希望能够回答更多问题。显然,我不希望读者阅读所有内容。

问题:

每当我运行我的应用程序并显示相同的视图(在解除它之后),我的控制台输出显示以前的绑定仍然存在。

详细信息:

我正在显示的视图如下:有一个tableview将其源绑定到我的ViewModel,每个单元格都有左/右标签绑定到ViewModel。

我将上面的视图创建为模态弹出视图。每个单元格将用户导航到他/她可以编辑该字段的新视图。转到新视图并使用“后退”按钮导航不会导致任何问题(据我所知)。一旦用户按下按钮以关闭模态弹出框(例如“取消”),下次显示视图时,旧的绑定似乎存在。在诊断下查看如何重复这些值。我不明白为什么。

我创建了我的tableview,并在GetOrCreateCellFor中为我遇到绑定问题的单元格创建了一个新的TimesheetOptionCell

代码背后:

在我ViewDidLoad()的{​​{1}}内,我设置了TimesheetEntryView

ItemsSource

var source = new TimesheetTableSource (TableView, this); var set = this.CreateBindingSet<TimesheetEntryView, TimesheetEntryViewModel> (); set.Bind (source).For (src => src.ItemsSource).To (vm => vm.Options); set.Apply (); TableView.Source = source; 内:

TimesheetTableSource

ObservableCollection<ViewModelBase> _options; public override System.Collections.IEnumerable ItemsSource { get { return _options; } set { _options = (ObservableCollection<ViewModelBase>)value; if (_options != null) { this.ReloadTableData (); } } } public override int NumberOfSections (UITableView tableView) { return 3; } public override int RowsInSection (UITableView tableview, int section) { if (section == 0) { return _options.Count; } else if (section == 1) { return 2; } else if (section == 2) { return 1; } else { return 0; } } protected override UITableViewCell GetOrCreateCellFor (UITableView tableView, NSIndexPath indexPath, object item) { if(indexPath.Section == 0) { return TimesheetOptionCell.Create (); } GenericOneLabelCell cell = GenericOneLabelCell.Create (); if (indexPath.Section == 1 && indexPath.Row == 0) { cell.LabelText = "Save"; var set = _timesheetView.CreateBindingSet<TimesheetEntryView, TimesheetEntryViewModel> (); set.Bind (cell).For (cll => cll.CellEnabled).To (vm => vm.SaveEnabled); set.Apply (); } else if (indexPath.Section == 1 && indexPath.Row == 1) { cell.LabelText = "Apply"; var set = _timesheetView.CreateBindingSet<TimesheetEntryView, TimesheetEntryViewModel> (); set.Bind (cell).For (cll => cll.CellEnabled).To (vm => vm.SaveEnabled); set.Apply (); } return cell; } 内:

TimesheetOptionCell

诊断

这是我第一次显示视图:

    public TimesheetOptionCell (IntPtr handle) : base (handle)
    {
        this.DelayBind (() => 
        {
            //set.bind(<label/textView>) implicitly adds .For("Text")
            var set = this.CreateBindingSet<TimesheetOptionCell, OptionViewModelBase>();
            set.Bind(FieldDescriptionTextView).To(option => option.OptionValue);
            set.Bind(FieldTitleLabel).To(option => option.Title);
            set.Apply();
        });
    }

    public static TimesheetOptionCell Create ()
    {
        return (TimesheetOptionCell)Nib.Instantiate (null, null) [0];
    }

第二次之后,我明白了:

2013-08-06 09:07:13.824 FCXiOSv2[16478:21e03] mvx: Diagnostic:   6.70 Showing ViewModel TimesheetEntryViewModel
2013-08-06 09:07:13.825 FCXiOSv2[16478:21e03] TouchNavigation: Diagnostic:   6.70 Navigate requested
2013-08-06 09:07:13.840 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.72 Receiving setValue to System.Collections.ObjectModel.ObservableCollection`1[FCX.Core.ViewModels.ViewModelBase]
2013-08-06 09:07:13.873 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.75 Receiving setValue to 7/23/2013
2013-08-06 09:07:13.874 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.75 Receiving setValue to Date Worked
2013-08-06 09:07:13.881 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.76 Receiving setValue to 0:00
2013-08-06 09:07:13.882 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.76 Receiving setValue to Time Worked
2013-08-06 09:07:13.888 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.77 Receiving setValue to 
2013-08-06 09:07:13.889 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.77 Receiving setValue to Company
2013-08-06 09:07:13.894 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.77 Receiving setValue to 
2013-08-06 09:07:13.894 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.77 Receiving setValue to Description
2013-08-06 09:07:13.899 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.78 Receiving setValue to False
2013-08-06 09:07:13.903 FCXiOSv2[16478:21e03] MvxBind: Diagnostic:   6.78 Receiving setValue to False

第10次之后:

2013-08-06 09:17:43.965 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 
2013-08-06 09:17:43.966 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 
2013-08-06 09:17:43.967 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 
2013-08-06 09:17:43.967 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 
2013-08-06 09:17:43.968 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 
2013-08-06 09:17:43.969 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 7/23/2013
2013-08-06 09:17:43.970 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 7/23/2013
2013-08-06 09:17:43.971 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 0:00
2013-08-06 09:17:43.972 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.85 Receiving setValue to 
2013-08-06 09:17:43.972 FCXiOSv2[16478:21e03] mvx: Diagnostic: 636.85 Showing ViewModel TimesheetEntryViewModel
2013-08-06 09:17:43.973 FCXiOSv2[16478:21e03] TouchNavigation: Diagnostic: 636.85 Navigate requested
2013-08-06 09:17:44.017 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.90 Receiving setValue to System.Collections.ObjectModel.ObservableCollection`1[FCX.Core.ViewModels.ViewModelBase]
2013-08-06 09:17:44.024 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.90 Receiving setValue to 7/23/2013
2013-08-06 09:17:44.025 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.90 Receiving setValue to Date Worked
2013-08-06 09:17:44.031 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.91 Receiving setValue to 0:00
2013-08-06 09:17:44.032 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.91 Receiving setValue to Time Worked
2013-08-06 09:17:44.042 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.92 Receiving setValue to 
2013-08-06 09:17:44.043 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.92 Receiving setValue to Company
2013-08-06 09:17:44.050 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.93 Receiving setValue to 
2013-08-06 09:17:44.050 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.93 Receiving setValue to Description
2013-08-06 09:17:44.053 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.93 Receiving setValue to False
2013-08-06 09:17:44.055 FCXiOSv2[16478:21e03] MvxBind: Diagnostic: 636.94 Receiving setValue to False

抱歉打扰你。谢谢!

1 个答案:

答案 0 :(得分:0)

  

视图消失后,为什么绑定会持续存在?

视图可以多次显示 - 它们可以显示,消失,再次出现等等 - 因此通常会在该视图的生命周期中设置绑定 - 而不仅仅是针对每个外观。

每个View将在处理时清除其绑定。恰好当Dispose发生在iOS和Xamarin.iOS时 - 它取决于UIKit何时决定清理内存。在模拟器中,您通常可以使用“模拟内存警告”菜单选项将其转发。

如果您希望View在某个时刻之前清除绑定,那么您可以自己调用this.ClearAllBindings() - 但在大多数情况下这不是必需的,因为View和ViewModel通常在一对中存在一生观点。


根据您的描述,我不确定我是否完全按照您在自定义视图展示器中的操作,也不确定在您的视图模型位置内 - 我不确定所有Resolve<> Result跟踪线的含义。我怀疑您可能正在重用ViewModels和/或Views,这可能是您的多重绑定发生的地方。