public override void ViewDidLoad() { base.ViewDidLoad(); prepareViews(); prepareOnboarding(); var source = new StartTimeEntryTableViewSource(SuggestionsTableView); SuggestionsTableView.Source = source; source.ToggleTasksCommand = new MvxCommand <ProjectSuggestion>(toggleTaskSuggestions); var invertedVisibilityConverter = new MvxInvertedVisibilityValueConverter(); var invertedBoolConverter = new BoolToConstantValueConverter <bool>(false, true); var buttonColorConverter = new BoolToConstantValueConverter <UIColor>( Color.StartTimeEntry.ActiveButton.ToNativeColor(), Color.StartTimeEntry.InactiveButton.ToNativeColor() ); var durationCombiner = new DurationValueCombiner(); var bindingSet = this.CreateBindingSet <StartTimeEntryViewController, StartTimeEntryViewModel>(); //TableView bindingSet.Bind(source) .For(v => v.ObservableCollection) .To(vm => vm.Suggestions); bindingSet.Bind(source) .For(v => v.UseGrouping) .To(vm => vm.UseGrouping); bindingSet.Bind(source) .For(v => v.SelectSuggestionCommand) .To(vm => vm.SelectSuggestionCommand); bindingSet.Bind(source) .For(v => v.CreateCommand) .To(vm => vm.CreateCommand); bindingSet.Bind(source) .For(v => v.IsSuggestingProjects) .To(vm => vm.IsSuggestingProjects); bindingSet.Bind(source) .For(v => v.Text) .To(vm => vm.CurrentQuery); bindingSet.Bind(source) .For(v => v.SuggestCreation) .To(vm => vm.SuggestCreation); bindingSet.Bind(source) .For(v => v.ShouldShowNoTagsInfoMessage) .To(vm => vm.ShouldShowNoTagsInfoMessage); bindingSet.Bind(source) .For(v => v.ShouldShowNoProjectsInfoMessage) .To(vm => vm.ShouldShowNoProjectsInfoMessage); //Text bindingSet.Bind(TimeInput) .For(v => v.Duration) .To(vm => vm.DisplayedTime) .Mode(MvxBindingMode.OneWayToSource); bindingSet.Bind(TimeLabel) .For(v => v.Text) .ByCombining(durationCombiner, vm => vm.DisplayedTime, vm => vm.DisplayedTimeFormat); bindingSet.Bind(Placeholder) .To(vm => vm.PlaceholderText); bindingSet.Bind(DescriptionRemainingLengthLabel) .To(vm => vm.DescriptionRemainingBytes); //Buttons bindingSet.Bind(TagsButton) .For(v => v.TintColor) .To(vm => vm.IsSuggestingTags) .WithConversion(buttonColorConverter); bindingSet.Bind(BillableButton) .For(v => v.TintColor) .To(vm => vm.IsBillable) .WithConversion(buttonColorConverter); bindingSet.Bind(ProjectsButton) .For(v => v.TintColor) .To(vm => vm.IsSuggestingProjects) .WithConversion(buttonColorConverter); bindingSet.Bind(DoneButton) .For(v => v.Enabled) .To(vm => vm.DescriptionLengthExceeded) .WithConversion(invertedBoolConverter); //Visibility bindingSet.Bind(BillableButtonWidthConstraint) .For(v => v.Constant) .To(vm => vm.IsBillableAvailable) .WithConversion(new BoolToConstantValueConverter <nfloat>(42, 0)); bindingSet.Bind(DescriptionRemainingLengthLabel) .For(v => v.BindVisible()) .To(vm => vm.DescriptionLengthExceeded) .WithConversion(invertedVisibilityConverter); //Commands bindingSet.Bind(DoneButton).To(vm => vm.DoneCommand); bindingSet.Bind(CloseButton).To(vm => vm.BackCommand); bindingSet.Bind(BillableButton).To(vm => vm.ToggleBillableCommand); bindingSet.Bind(StartDateButton).To(vm => vm.SetStartDateCommand); bindingSet.Bind(DateTimeButton).To(vm => vm.ChangeTimeCommand); bindingSet.Bind(TagsButton).To(vm => vm.ToggleTagSuggestionsCommand); bindingSet.Bind(ProjectsButton).To(vm => vm.ToggleProjectSuggestionsCommand); bindingSet.Apply(); // Reactive this.Bind(ViewModel.TextFieldInfoObservable, onTextFieldInfo); this.Bind( DescriptionTextView .AttributedText() .Select(attributedString => attributedString.Length == 0), isDescriptionEmptySubject); DescriptionTextView.AttributedText() .CombineLatest(DescriptionTextView.CursorPosition(), (text, _) => text) .Where(_ => !isUpdatingDescriptionField) .SubscribeOn(ThreadPoolScheduler.Instance) .Do(_ => updatePlaceholder()) .Select(text => text.AsImmutableSpans((int)DescriptionTextView.SelectedRange.Location)) .ObserveOn(SynchronizationContext.Current) .Subscribe(async info => await ViewModel.OnTextFieldInfoFromView(info)) .DisposedBy(DisposeBag); }