public SpecialEpisodeFormViewModel( SpecialEpisode episode, SeriesFormViewModel parent, IObservable <int> maxSequenceNumber, ResourceManager?resourceManager, IScheduler?scheduler = null) : base(parent, maxSequenceNumber, resourceManager, scheduler) { this.SpecialEpisode = episode; this.CopyProperties(); this.ChannelRule = this.ValidationRule( vm => vm.Channel, channel => !String.IsNullOrWhiteSpace(channel), "ChannelEmpty"); this.YearRule = this.ValidationRule(vm => vm.Year, SeriesMinYear, SeriesMaxYear, nameof(this.Year)); this.PosterUrlRule = this.ValidationRule(vm => vm.PosterUrl, url => url.IsUrl(), "PosterUrlInvalid"); this.InitializeValueDependencies(); this.CanAlwaysDelete(); this.EnableChangeTracking(); }
public SeasonFormViewModel( Season season, SeriesFormViewModel parent, IObservable <int> maxSequenceNumber, ResourceManager?resourceManager = null, IScheduler?scheduler = null) : base(parent, maxSequenceNumber, resourceManager, scheduler) { this.Season = season; var canDeletePeriod = this.periodsSource.Connect() .Count() .Select(count => count > MinPeriodCount); this.periodsSource.Connect() .Sort(SortExpressionComparer <Period> .Ascending(period => period.StartYear) .ThenByAscending(period => period.StartMonth) .ThenByAscending(period => period.EndYear) .ThenByAscending(period => period.EndMonth)) .Transform(period => this.CreatePeriodForm(period, canDeletePeriod)) .Bind(out this.periods) .DisposeMany() .Subscribe(); this.CopyProperties(); this.ChannelRule = this.ValidationRule( vm => vm.Channel, channel => !String.IsNullOrWhiteSpace(channel), "ChannelEmpty"); this.PeriodsNonOverlapping = this.periods.ToObservableChangeSet() .AutoRefreshOnObservable(pvm => pvm.Changed) .Select(_ => this.AreAllPeriodsNonOverlapping()); this.WhenAnyValue(vm => vm.CurrentPosterIndex) .Select(index => this.Season.Periods[index].PosterUrl) .BindTo(this, vm => vm.CurrentPosterUrl); var canAddPeriod = this.Periods.ToObservableChangeSet() .AutoRefreshOnObservable(period => period.Valid) .ToCollection() .Select(periods => periods.Count < MaxPeriodCount && periods.All(period => !period.HasErrors)) .CombineLatest(this.PeriodsNonOverlapping, (a, b) => a && b); this.AddPeriod = ReactiveCommand.Create(this.OnAddPeriod, canAddPeriod); var canSwitchToNextPoster = this.WhenAnyValue(vm => vm.CurrentPosterIndex) .Merge(this.Save.Select(_ => this.CurrentPosterIndex)) .Select(index => index != this.Season.Periods.Count - 1 && this.Season.Periods.Skip(index + 1).Any(period => period.PosterUrl != null)); var canSwitchToPreviousPoster = this.WhenAnyValue(vm => vm.CurrentPosterIndex) .Merge(this.Save.Select(_ => this.CurrentPosterIndex)) .Select(index => index != 0 && this.Season.Periods.Take(index).Any(period => period.PosterUrl != null)); this.SwitchToNextPoster = ReactiveCommand.Create( () => this.SetCurrentPosterIndex(index => index + 1), canSwitchToNextPoster); this.SwitchToPreviousPoster = ReactiveCommand.Create( () => this.SetCurrentPosterIndex(index => index - 1), canSwitchToPreviousPoster); this.Save.Discard() .Merge(this.GoToSeries.Discard()) .Delay(TimeSpan.FromMilliseconds(500), this.Scheduler) .Subscribe(() => this.CurrentPosterIndex = 0); this.CanAlwaysDelete(); this.EnableChangeTracking(); }