public void FailsForFormatsWhichAreNotDateFormat(object parameter)
                {
                    var combiner   = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Utc, true);
                    var successful = tryGetValue(combiner, DateTimeOffset.UtcNow, parameter, out var convertedValue);

                    successful.Should().BeFalse();
                    convertedValue.Should().Be(MvxBindingConstant.UnsetValue);
                }
                public void WorksForValidFormats(DateFormat format)
                {
                    var now        = DateTimeOffset.Now;
                    var combiner   = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Utc, true);
                    var successful = tryGetValue(combiner, now, format, out var convertedValue);

                    successful.Should().BeTrue();
                    convertedValue.Should().BeOfType <string>();
                    convertedValue.Should().Be(now.ToString(format.Long));
                }
        private static bool tryGetValue(DateTimeOffsetDateFormatValueCombiner combiner, DateTimeOffset duration, object format, out object convertedValue)
        {
            var dateStepDescription = new MvxLiteralSourceStepDescription();

            dateStepDescription.Literal = duration;

            var formatStepDescription = new MvxLiteralSourceStepDescription();

            formatStepDescription.Literal = format;

            var steps = new[]
            {
                new MvxLiteralSourceStep(dateStepDescription),
                new MvxLiteralSourceStep(formatStepDescription)
            };

            return(combiner.TryGetValue(steps, out convertedValue));
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            setupDismissingByTappingOnBackground();
            prepareViews();

            var durationCombiner            = new DurationValueCombiner();
            var dateCombiner                = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local);
            var timeCombiner                = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local);
            var visibilityConverter         = new MvxVisibilityValueConverter();
            var invertedBoolConverter       = new BoolToConstantValueConverter <bool>(false, true);
            var inverterVisibilityConverter = new MvxInvertedVisibilityValueConverter();
            var projectTaskClientCombiner   = new ProjectTaskClientValueCombiner(
                ProjectTaskClientLabel.Font.CapHeight,
                Color.EditTimeEntry.ClientText.ToNativeColor(),
                false
                );
            var stopRunningTimeEntryAndEditDurationForStoppedConverter = new BoolToConstantValueConverter <IMvxCommand>(
                ViewModel.StopCommand, ViewModel.EditDurationCommand);

            var bindingSet = this.CreateBindingSet <EditTimeEntryViewController, EditTimeEntryViewModel>();

            //Error message view
            bindingSet.Bind(ErrorMessageLabel)
            .For(v => v.Text)
            .To(vm => vm.SyncErrorMessage);

            bindingSet.Bind(ErrorView)
            .For(v => v.BindTap())
            .To(vm => vm.DismissSyncErrorMessageCommand);

            bindingSet.Bind(ErrorView)
            .For(v => v.BindVisible())
            .To(vm => vm.SyncErrorMessageVisible)
            .WithConversion(inverterVisibilityConverter);

            //Text
            bindingSet.Bind(DescriptionTextView)
            .For(v => v.RemainingLength)
            .To(vm => vm.DescriptionRemainingLength);

            bindingSet.Bind(DescriptionTextView)
            .For(v => v.BindText())
            .To(vm => vm.Description);

            bindingSet.Bind(BillableSwitch)
            .For(v => v.BindAnimatedOn())
            .To(vm => vm.Billable);

            bindingSet.Bind(DurationLabel)
            .ByCombining(durationCombiner,
                         vm => vm.Duration,
                         vm => vm.DurationFormat);

            bindingSet.Bind(ProjectTaskClientLabel)
            .For(v => v.AttributedText)
            .ByCombining(projectTaskClientCombiner,
                         v => v.Project,
                         v => v.Task,
                         v => v.Client,
                         v => v.ProjectColor);

            bindingSet.Bind(StartDateLabel)
            .ByCombining(dateCombiner,
                         vm => vm.StartTime,
                         vm => vm.DateFormat);

            bindingSet.Bind(StartTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StartTime,
                         vm => vm.TimeFormat);

            bindingSet.Bind(EndTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StopTime,
                         vm => vm.TimeFormat);

            //Commands
            bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand);
            bindingSet.Bind(DeleteButton).To(vm => vm.DeleteCommand);
            bindingSet.Bind(ConfirmButton).To(vm => vm.ConfirmCommand);

            bindingSet.Bind(DurationView)
            .For(v => v.BindTap())
            .To(vm => vm.EditDurationCommand);

            bindingSet.Bind(StartTimeView)
            .For(v => v.BindTap())
            .To(vm => vm.EditDurationCommand);

            bindingSet.Bind(StopButton)
            .To(vm => vm.StopCommand);

            bindingSet.Bind(EndTimeView)
            .For(v => v.BindTap())
            .To(vm => vm.IsTimeEntryRunning)
            .WithConversion(stopRunningTimeEntryAndEditDurationForStoppedConverter);

            bindingSet.Bind(ProjectTaskClientLabel)
            .For(v => v.BindTap())
            .To(vm => vm.SelectProjectCommand);

            bindingSet.Bind(AddProjectAndTaskView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectProjectCommand);

            bindingSet.Bind(StartDateView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectStartDateCommand);

            bindingSet.Bind(TagsTextView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectTagsCommand);

            bindingSet.Bind(AddTagsView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectTagsCommand);

            bindingSet.Bind(BillableView)
            .For(v => v.BindTap())
            .To(vm => vm.ToggleBillableCommand);

            //End time and the stop button visibility
            bindingSet.Bind(StopButton)
            .For(v => v.BindVisible())
            .To(vm => vm.IsTimeEntryRunning)
            .WithConversion(inverterVisibilityConverter);

            bindingSet.Bind(EndTimeLabel)
            .For(v => v.BindVisible())
            .To(vm => vm.IsTimeEntryRunning)
            .WithConversion(visibilityConverter);

            //Project visibility
            bindingSet.Bind(AddProjectAndTaskView)
            .For(v => v.BindVisible())
            .To(vm => vm.Project)
            .WithConversion(visibilityConverter);

            bindingSet.Bind(ProjectTaskClientLabel)
            .For(v => v.BindVisible())
            .To(vm => vm.Project)
            .WithConversion(inverterVisibilityConverter);

            //Tags visibility
            bindingSet.Bind(AddTagsView)
            .For(v => v.BindVisible())
            .To(vm => vm.HasTags)
            .WithConversion(visibilityConverter);

            bindingSet.Bind(TagsTextView)
            .For(v => v.BindVisible())
            .To(vm => vm.HasTags)
            .WithConversion(inverterVisibilityConverter);

            //Confirm button enabled
            bindingSet.Bind(ConfirmButton)
            .For(v => v.Enabled)
            .To(vm => vm.DescriptionLimitExceeded)
            .WithConversion(invertedBoolConverter);

            bindingSet.Bind(ConfirmButton)
            .For(v => v.Alpha)
            .To(vm => vm.DescriptionLimitExceeded)
            .WithConversion(new BoolToConstantValueConverter <nfloat>(0.5f, 1));

            bindingSet.Bind(BillableView)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsBillableAvailable)
            .WithConversion(visibilityConverter);

            bindingSet.Apply();
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            TitleLabel.Text                  = Resources.Edit;
            BillableLabel.Text               = Resources.Billable;
            StartDateDescriptionLabel.Text   = Resources.Startdate;
            DurationDescriptionLabel.Text    = Resources.Duration;
            StartDescriptionLabel.Text       = Resources.Start;
            EndDescriptionLabel.Text         = Resources.End;
            ErrorMessageTitleLabel.Text      = Resources.Oops;
            AddProjectTaskLabel.Text         = Resources.AddProjectTask;
            CategorizeWithProjectsLabel.Text = Resources.CategorizeYourTimeWithProjects;
            AddTagsLabel.Text                = Resources.AddTags;
            DeleteButton.SetTitle(Resources.Delete, UIControlState.Normal);
            ConfirmButton.SetTitle(Resources.ConfirmChanges, UIControlState.Normal);

            prepareViews();
            prepareOnboarding();

            contentSizeChangedDisposable = ScrollViewContent.AddObserver(boundsKey, NSKeyValueObservingOptions.New, onContentSizeChanged);

            var durationCombiner            = new DurationValueCombiner();
            var dateCombiner                = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local);
            var timeCombiner                = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local);
            var visibilityConverter         = new MvxVisibilityValueConverter();
            var invertedBoolConverter       = new BoolToConstantValueConverter <bool>(false, true);
            var inverterVisibilityConverter = new MvxInvertedVisibilityValueConverter();
            var projectTaskClientCombiner   = new ProjectTaskClientValueCombiner(
                ProjectTaskClientLabel.Font.CapHeight,
                Color.EditTimeEntry.ClientText.ToNativeColor(),
                false
                );
            var stopRunningTimeEntryAndSelectStopTimeForStoppedConverter = new BoolToConstantValueConverter <IMvxCommand>(
                ViewModel.StopCommand, ViewModel.SelectStopTimeCommand);

            var isInaccessibleTextColorConverter = new BoolToConstantValueConverter <UIColor>(
                Color.Common.Disabled.ToNativeColor(),
                Color.Common.TextColor.ToNativeColor()
                );

            var showTagsCombiner = new ShowTagsValueCombiner();

            var bindingSet = this.CreateBindingSet <EditTimeEntryViewController, EditTimeEntryViewModel>();

            //Error message view
            bindingSet.Bind(ErrorMessageLabel)
            .For(v => v.Text)
            .To(vm => vm.SyncErrorMessage);

            bindingSet.Bind(ErrorView)
            .For(v => v.BindTap())
            .To(vm => vm.DismissSyncErrorMessageCommand);

            bindingSet.Bind(ErrorView)
            .For(v => v.BindVisible())
            .To(vm => vm.SyncErrorMessageVisible)
            .WithConversion(inverterVisibilityConverter);

            //Text
            bindingSet.Bind(RemainingCharacterCount)
            .To(vm => vm.DescriptionRemainingLength);

            bindingSet.Bind(RemainingCharacterCount)
            .For(v => v.BindVisible())
            .To(vm => vm.DescriptionLimitExceeded);

            bindingSet.Bind(DescriptionTextView)
            .For(v => v.BindText())
            .To(vm => vm.Description);

            bindingSet.Bind(DescriptionTextView)
            .For(v => v.BindDidBecomeFirstResponder())
            .To(vm => vm.StartEditingDescriptionCommand);

            bindingSet.Bind(DurationLabel)
            .ByCombining(durationCombiner,
                         vm => vm.Duration,
                         vm => vm.DurationFormat);

            bindingSet.Bind(ProjectTaskClientLabel)
            .For(v => v.AttributedText)
            .ByCombining(projectTaskClientCombiner,
                         v => v.Project,
                         v => v.Task,
                         v => v.Client,
                         v => v.ProjectColor);

            bindingSet.Bind(StartDateLabel)
            .ByCombining(dateCombiner,
                         vm => vm.StartTime,
                         vm => vm.DateFormat);

            bindingSet.Bind(StartTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StartTime,
                         vm => vm.TimeFormat);

            bindingSet.Bind(EndTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StopTime,
                         vm => vm.TimeFormat);

            //Commands
            bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand);
            bindingSet.Bind(DeleteButton).To(vm => vm.DeleteCommand);
            bindingSet.Bind(ConfirmButton).To(vm => vm.SaveCommand);

            bindingSet.Bind(DurationView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectDurationCommand);

            bindingSet.Bind(StartTimeView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectStartTimeCommand);

            bindingSet.Bind(StopButton)
            .To(vm => vm.StopCommand);

            bindingSet.Bind(EndTimeView)
            .For(v => v.BindTap())
            .To(vm => vm.IsTimeEntryRunning)
            .WithConversion(stopRunningTimeEntryAndSelectStopTimeForStoppedConverter);

            bindingSet.Bind(ProjectTaskClientLabel)
            .For(v => v.BindTap())
            .To(vm => vm.SelectProjectCommand);

            bindingSet.Bind(AddProjectAndTaskView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectProjectCommand);

            bindingSet.Bind(StartDateView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectStartDateCommand);

            bindingSet.Bind(TagsTextView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectTagsCommand);

            bindingSet.Bind(AddTagsView)
            .For(v => v.BindTap())
            .To(vm => vm.SelectTagsCommand);

            bindingSet.Bind(BillableSwitch)
            .For(v => v.BindValueChanged())
            .To(vm => vm.ToggleBillableCommand);

            //End time and the stop button visibility
            bindingSet.Bind(StopButton)
            .For(v => v.BindVisible())
            .To(vm => vm.IsTimeEntryRunning)
            .WithConversion(inverterVisibilityConverter);

            bindingSet.Bind(EndTimeLabel)
            .For(v => v.BindVisible())
            .To(vm => vm.IsTimeEntryRunning)
            .WithConversion(visibilityConverter);

            //Project visibility
            bindingSet.Bind(AddProjectAndTaskView)
            .For(v => v.BindVisible())
            .To(vm => vm.Project)
            .WithConversion(visibilityConverter);

            bindingSet.Bind(ProjectTaskClientLabel)
            .For(v => v.BindVisible())
            .To(vm => vm.Project)
            .WithConversion(inverterVisibilityConverter);

            //Tags visibility
            bindingSet.Bind(AddTagsView)
            .For(v => v.BindVisible())
            .To(vm => vm.HasTags)
            .WithConversion(visibilityConverter);

            bindingSet.Bind(TagsTextView)
            .For(v => v.BindVisible())
            .To(vm => vm.HasTags)
            .WithConversion(inverterVisibilityConverter);

            //Confirm button enabled
            bindingSet.Bind(ConfirmButton)
            .For(v => v.Enabled)
            .To(vm => vm.DescriptionLimitExceeded)
            .WithConversion(invertedBoolConverter);

            bindingSet.Bind(ConfirmButton)
            .For(v => v.Alpha)
            .To(vm => vm.DescriptionLimitExceeded)
            .WithConversion(new BoolToConstantValueConverter <nfloat>(0.5f, 1));

            bindingSet.Bind(BillableView)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsBillableAvailable)
            .WithConversion(visibilityConverter);

            //Regarding inaccessible entries
            getLabelsToChangeColorWhenEditingInaccessibleEntry().ForEach(createTextColorBindingForInaccessibleEntries);

            bindingSet.Bind(DescriptionTextView)
            .For(v => v.TextColor)
            .To(vm => vm.IsInaccessible)
            .WithConversion(isInaccessibleTextColorConverter);

            bindingSet.Bind(DescriptionTextView)
            .For(v => v.UserInteractionEnabled)
            .To(vm => vm.IsInaccessible)
            .WithConversion(invertedBoolConverter);

            bindingSet.Bind(BillableSwitch)
            .For(v => v.Enabled)
            .To(vm => vm.IsInaccessible)
            .WithConversion(invertedBoolConverter);

            bindingSet.Bind(TagsContainerView)
            .For(v => v.Hidden)
            .ByCombining(showTagsCombiner,
                         vm => vm.IsInaccessible,
                         vm => vm.HasTags)
            .WithConversion(invertedBoolConverter);

            bindingSet.Bind(TagsSeparator)
            .For(v => v.Hidden)
            .ByCombining(showTagsCombiner,
                         vm => vm.IsInaccessible,
                         vm => vm.HasTags)
            .WithConversion(invertedBoolConverter);

            bindingSet.Apply();

            void createTextColorBindingForInaccessibleEntries(UILabel label)
            {
                bindingSet.Bind(label)
                .For(v => v.TextColor)
                .To(vm => vm.IsInaccessible)
                .WithConversion(isInaccessibleTextColorConverter);
            }
        }
Beispiel #6
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            startTimeChangingSubscription = ViewModel.StartTimeChanging.Subscribe(startTimeChanging);

            setupDismissingByTappingOnBackground();
            prepareViews();

            var durationCombiner              = new DurationValueCombiner();
            var timeCombiner                  = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local);
            var dateCombiner                  = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local, useLongFormat: false);
            var timeFormatToLocaleConverter   = new TimeFormatToLocaleValueConverter();
            var inverseBoolConverter          = new BoolToConstantValueConverter <bool>(false, true);
            var editedTimeLabelColorConverter = new BoolToConstantValueConverter <UIColor>(
                Color.EditDuration.EditedTime.ToNativeColor(),
                Color.EditDuration.NotEditedTime.ToNativeColor());

            var bindingSet = this.CreateBindingSet <EditDurationViewController, EditDurationViewModel>();

            //Commands
            bindingSet.Bind(SaveButton).To(vm => vm.SaveCommand);
            bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand);

            //Start and stop date/time
            bindingSet.Bind(StartTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StartTime,
                         vm => vm.TimeFormat);

            bindingSet.Bind(StartDateLabel)
            .ByCombining(dateCombiner,
                         vm => vm.StartTime,
                         vm => vm.DateFormat);

            bindingSet.Bind(EndTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StopTime,
                         vm => vm.TimeFormat);

            bindingSet.Bind(EndDateLabel)
            .ByCombining(dateCombiner,
                         vm => vm.StopTime,
                         vm => vm.DateFormat);

            //Editing start and end time
            bindingSet.Bind(StartView)
            .For(v => v.BindTap())
            .To(vm => vm.EditStartTimeCommand);

            bindingSet.Bind(EndView)
            .For(v => v.BindTap())
            .To(vm => vm.EditStopTimeCommand);

            bindingSet.Bind(SetEndButton)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsRunning)
            .WithConversion(inverseBoolConverter);

            bindingSet.Bind(SetEndButton)
            .To(vm => vm.EditStopTimeCommand);

            //Visiblity
            bindingSet.Bind(EndTimeLabel)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsRunning);

            bindingSet.Bind(EndDateLabel)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsRunning);

            //Stard and end colors
            bindingSet.Bind(StartTimeLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStartTime)
            .WithConversion(editedTimeLabelColorConverter);

            bindingSet.Bind(StartDateLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStartTime)
            .WithConversion(editedTimeLabelColorConverter);

            bindingSet.Bind(EndTimeLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStopTime)
            .WithConversion(editedTimeLabelColorConverter);

            bindingSet.Bind(EndDateLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStopTime)
            .WithConversion(editedTimeLabelColorConverter);

            //Date picker
            bindingSet.Bind(DatePickerContainer)
            .For(v => v.BindAnimatedVisibility())
            .To(vm => vm.IsEditingTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.BindDateTimeOffset())
            .To(vm => vm.EditedTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.MaximumDate)
            .To(vm => vm.MaximumDateTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.MinimumDate)
            .To(vm => vm.MinimumDateTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.Locale)
            .To(vm => vm.TimeFormat)
            .WithConversion(timeFormatToLocaleConverter);

            //The wheel
            bindingSet.Bind(DurationInput)
            .For(v => v.UserInteractionEnabled)
            .To(vm => vm.IsEditingTime)
            .WithConversion(inverseBoolConverter);

            bindingSet.Bind(DurationInput)
            .For(v => v.Duration)
            .To(vm => vm.Duration);

            bindingSet.Bind(DurationInput)
            .For(v => v.FormattedDuration)
            .ByCombining(durationCombiner,
                         vm => vm.Duration,
                         vm => vm.DurationFormat);

            bindingSet.Bind(WheelView)
            .For(v => v.UserInteractionEnabled)
            .To(vm => vm.IsEditingTime)
            .WithConversion(inverseBoolConverter);

            bindingSet.Bind(WheelView)
            .For(v => v.MaximumStartTime)
            .To(vm => vm.MaximumStartTime);

            bindingSet.Bind(WheelView)
            .For(v => v.MinimumStartTime)
            .To(vm => vm.MinimumStartTime);

            bindingSet.Bind(WheelView)
            .For(v => v.MaximumEndTime)
            .To(vm => vm.MaximumStopTime);

            bindingSet.Bind(WheelView)
            .For(v => v.MinimumEndTime)
            .To(vm => vm.MinimumStopTime);

            bindingSet.Bind(WheelView)
            .For(v => v.StartTime)
            .To(vm => vm.StartTime);

            bindingSet.Bind(WheelView)
            .For(v => v.EndTime)
            .To(vm => vm.StopTime);

            bindingSet.Bind(WheelView)
            .For(v => v.IsRunning)
            .To(vm => vm.IsRunning);

            bindingSet.Apply();
        }
Beispiel #7
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            startTimeChangingSubscription = ViewModel.StartTimeChanging.Subscribe(startTimeChanging);

            prepareViews();

            var durationCombiner              = new DurationValueCombiner();
            var timeCombiner                  = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local);
            var dateCombiner                  = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local, useLongFormat: false);
            var timeFormatToLocaleConverter   = new TimeFormatToLocaleValueConverter();
            var inverseBoolConverter          = new BoolToConstantValueConverter <bool>(false, true);
            var editedTimeLabelColorConverter = new BoolToConstantValueConverter <UIColor>(
                Color.EditDuration.EditedTime.ToNativeColor(),
                Color.EditDuration.NotEditedTime.ToNativeColor());

            var bindingSet = this.CreateBindingSet <EditDurationViewController, EditDurationViewModel>();

            //Commands
            bindingSet.Bind(SaveButton).To(vm => vm.SaveCommand);
            bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand);

            //Start and stop date/time
            bindingSet.Bind(StartTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StartTime,
                         vm => vm.TimeFormat);

            bindingSet.Bind(StartDateLabel)
            .ByCombining(dateCombiner,
                         vm => vm.StartTime,
                         vm => vm.DateFormat);

            bindingSet.Bind(EndTimeLabel)
            .ByCombining(timeCombiner,
                         vm => vm.StopTime,
                         vm => vm.TimeFormat);

            bindingSet.Bind(EndDateLabel)
            .ByCombining(dateCombiner,
                         vm => vm.StopTime,
                         vm => vm.DateFormat);

            //Editing start and end time
            bindingSet.Bind(StartView)
            .For(v => v.BindTap())
            .To(vm => vm.EditStartTimeCommand);

            bindingSet.Bind(EndView)
            .For(v => v.BindTap())
            .To(vm => vm.EditStopTimeCommand);

            bindingSet.Bind(SetEndButton)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsRunning)
            .WithConversion(inverseBoolConverter);

            bindingSet.Bind(SetEndButton)
            .To(vm => vm.EditStopTimeCommand);

            //Visibility
            bindingSet.Bind(EndTimeLabel)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsRunning);

            bindingSet.Bind(EndDateLabel)
            .For(v => v.BindVisibility())
            .To(vm => vm.IsRunning);

            //Stard and end colors
            bindingSet.Bind(StartTimeLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStartTime)
            .WithConversion(editedTimeLabelColorConverter);

            bindingSet.Bind(StartDateLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStartTime)
            .WithConversion(editedTimeLabelColorConverter);

            bindingSet.Bind(EndTimeLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStopTime)
            .WithConversion(editedTimeLabelColorConverter);

            bindingSet.Bind(EndDateLabel)
            .For(v => v.TextColor)
            .To(vm => vm.IsEditingStopTime)
            .WithConversion(editedTimeLabelColorConverter);

            //Date picker
            bindingSet.Bind(DatePickerContainer)
            .For(v => v.BindAnimatedVisibility())
            .To(vm => vm.IsEditingTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.BindDateTimeOffset())
            .To(vm => vm.EditedTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.MaximumDate)
            .To(vm => vm.MaximumDateTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.MinimumDate)
            .To(vm => vm.MinimumDateTime);

            bindingSet.Bind(DatePicker)
            .For(v => v.Locale)
            .To(vm => vm.TimeFormat)
            .WithConversion(timeFormatToLocaleConverter);

            //The wheel
            bindingSet.Bind(DurationInput)
            .For(v => v.UserInteractionEnabled)
            .To(vm => vm.IsEditingTime)
            .WithConversion(inverseBoolConverter);

            bindingSet.Bind(DurationInput)
            .For(v => v.Duration)
            .To(vm => vm.Duration);

            bindingSet.Bind(DurationInput)
            .For(v => v.FormattedDuration)
            .ByCombining(durationCombiner,
                         vm => vm.Duration,
                         vm => vm.DurationFormat);

            bindingSet.Bind(WheelView)
            .For(v => v.UserInteractionEnabled)
            .To(vm => vm.IsEditingTime)
            .WithConversion(inverseBoolConverter);

            bindingSet.Bind(WheelView)
            .For(v => v.MaximumStartTime)
            .To(vm => vm.MaximumStartTime);

            bindingSet.Bind(WheelView)
            .For(v => v.MinimumStartTime)
            .To(vm => vm.MinimumStartTime);

            bindingSet.Bind(WheelView)
            .For(v => v.MaximumEndTime)
            .To(vm => vm.MaximumStopTime);

            bindingSet.Bind(WheelView)
            .For(v => v.MinimumEndTime)
            .To(vm => vm.MinimumStopTime);

            bindingSet.Bind(WheelView)
            .For(v => v.StartTime)
            .To(vm => vm.StartTime);

            bindingSet.Bind(WheelView)
            .For(v => v.EndTime)
            .To(vm => vm.StopTime);

            bindingSet.Bind(WheelView)
            .For(v => v.IsRunning)
            .To(vm => vm.IsRunning);

            bindingSet.Apply();

            // Interaction observables for analytics

            var editingStart = Observable.Merge(
                StartView.Rx().Tap().Select(true),
                EndView.Rx().Tap().Select(false)
                );

            var dateComponentChanged = DatePicker.Rx().DateComponent()
                                       .WithLatestFrom(editingStart,
                                                       (_, isStart) => isStart ? EditTimeSource.BarrelStartDate : EditTimeSource.BarrelStopDate
                                                       );

            var timeComponentChanged = DatePicker.Rx().TimeComponent()
                                       .WithLatestFrom(editingStart,
                                                       (_, isStart) => isStart ? EditTimeSource.BarrelStartTime : EditTimeSource.BarrelStopTime
                                                       );

            var durationInputChanged = Observable
                                       .FromEventPattern(e => DurationInput.DurationChanged += e, e => DurationInput.DurationChanged -= e)
                                       .Select(EditTimeSource.NumpadDuration);

            Observable.Merge(
                dateComponentChanged,
                timeComponentChanged,
                WheelView.TimeEdited,
                durationInputChanged
                )
            .Distinct()
            .Subscribe(ViewModel.TimeEditedWithSource)
            .DisposedBy(disposeBag);
        }