public ItemEditorViewModel( IManualTagEditor tagEdiotr, IItemService itemService, FileVersionListViewModel fileVersionList, INotificationCenterService notificationCenter, ILibraryManagementService libraryManagement, IFileItemLinkService fileItemLinkService, OpenFileCommand openFile, FileToClipboardCommand fileToClipboard, ISettingsService settingsService, IThumbnailManagementService thumbnailManagementService) { this.TagEditor = tagEdiotr; this._itemService = itemService; FileVersionList = fileVersionList; this.notificationCenter = notificationCenter; this.libraryManagement = libraryManagement; this.fileItemLinkService = fileItemLinkService; OpenFile = openFile; FileToClipboard = fileToClipboard; this.thumbnailManagementService = thumbnailManagementService; this.TagEditor.Editmode = true; this.TagEditor.CompletePool = true; this.TagEditor.PermitNewTags = true; this.disposables.Add(_selectedItemIdChanges); this.SelectedItemChanges = this._itemService .GetExtended(this.SelectedItemIdChanges) .TakeUntil(destroy); this.Save = new RelayCommand(_ => _save()); this.CreateThumbnail = new RelayCommand(_ => createThumbnail()); var selectedVersionChanges = this.WhenAnyValue(x => x.SelectedVersion).TakeUntil(destroy); var curLink = this.newLinks.Connect() .ChangeKey(link => link.Version) .WatchValue(selectedVersionChanges, link => link.Version); var curFileFilter = selectedVersionChanges.CombineLatest(SelectedItemChanges, (version, item) => new { version, item }) .Select( x => { return(new Func <VersionedFile, bool>((VersionedFile vFile) => x.version.HasValue && x.item.HasValue && (vFile.Version == x.version.Value) && (vFile.ItemId == x.item.Value.ItemId))); }); var files = this.fileItemLinkService.BuildversionedFiles(newLinks.Connect()); var curFiles = files.Filter(curFileFilter) .Select(x => x.FirstOrDefault(x => x.Reason != ChangeReason.Remove).Current.ToNullable()); this._selectedFiles = curFiles .TakeUntil(destroy) .ToProperty(this, nameof(SelectedFiles)); this._cameraRotationMode = settingsService .WhenAnyValue(x => x.CameraRotationMode) .Select(x => (CameraRotationMode)x) .ToProperty(this, nameof(CameraRotationMode)); _cameraRotationMode.DisposeWith(disposables); DateTime mostRecentRequest = default; curFiles .ObserveOn(RxApp.TaskpoolScheduler) .TakeUntil(destroy) .Select(files => { mostRecentRequest = DateTime.Now; var orderTime = DateTime.Now; if (!files.HasValue || files?.File.AbsolutePath == null) { return(null); } this.MaterialBrush = new SolidColorBrush(Colors.LightGray); var mat = new DiffuseMaterial(this.MaterialBrush); ModelImporter importer = new ModelImporter() { DefaultMaterial = mat }; Model3DGroup model = importer.Load(files.Value.File.AbsolutePath); model.SetMaterial(mat); model.PlaceAtOrigin(); model.Freeze(); return(new { timestamp = mostRecentRequest, model }); }) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => { this.ViewportContent = null; if (x == null) { return; } LoadingModel = true; RxApp.MainThreadScheduler.Schedule(x.model, (_, model) => { if (x.timestamp == mostRecentRequest) { this.ViewportContent = model; LoadingModel = false; } return(null); }); }); var linkFilter = selectedVersionChanges.Select(version => new Func <FileItemLink, bool>(link => link.Version == version) ); var selectedLinkChanges = this.newLinks .Connect() .RemoveKey() .Filter(linkFilter) .Select(x => x.FirstOrDefault().Item.Current); this.SelectedItemChanges.Subscribe( LoadItem, ex => this.notificationCenter.OnError(ex)); }