internal TouchElementViewModel(TouchElement touch) { CultureInfo culture = CultureInfo.InvariantCulture; CompositeDisposable treeItemDisposable = new CompositeDisposable(); CompositeDisposable listItemDisposable = new CompositeDisposable(); LocationX = touch .ToReactivePropertyAsSynchronized( x => x.LocationX, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); LocationY = touch .ToReactivePropertyAsSynchronized( x => x.LocationY, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); SizeX = touch .ToReactivePropertyAsSynchronized( x => x.SizeX, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.NonNegative, out result, out message); return(message); }) .AddTo(disposable); SizeY = touch .ToReactivePropertyAsSynchronized( x => x.SizeY, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.NonNegative, out result, out message); return(message); }) .AddTo(disposable); JumpScreen = touch .ToReactivePropertyAsSynchronized(x => x.JumpScreen) .AddTo(disposable); SoundEntries = touch.SoundEntries .ToReadOnlyReactiveCollection(x => new SoundEntryViewModel(x)) .AddTo(disposable); CommandEntries = touch.CommandEntries .ToReadOnlyReactiveCollection(x => new CommandEntryViewModel(x)) .AddTo(disposable); Layer = touch .ToReactivePropertyAsSynchronized(x => x.Layer) .AddTo(disposable); TreeItem = touch .ObserveProperty(x => x.TreeItem) .Do(_ => TreeItem?.Value.Dispose()) .Select(x => new TreeViewItemViewModel(x)) .ToReactiveProperty() .AddTo(disposable); TreeItem.Subscribe(x => { treeItemDisposable.Dispose(); treeItemDisposable = new CompositeDisposable(); x.PropertyChangedAsObservable() .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.None) .Subscribe(_ => TreeItem.ForceNotify()) .AddTo(treeItemDisposable); }) .AddTo(disposable); SelectedTreeItem = touch .ToReactivePropertyAsSynchronized( x => x.SelectedTreeItem, x => TreeItem.Value.SearchViewModel(x), x => x?.Model ) .AddTo(disposable); ListColumns = touch.ListColumns .ToReadOnlyReactiveCollection(x => new ListViewColumnHeaderViewModel(x)) .AddTo(disposable); ListItems = touch.ListItems .ToReadOnlyReactiveCollection(x => new ListViewItemViewModel(x)) .AddTo(disposable); SelectedListItem = touch .ToReactivePropertyAsSynchronized( x => x.SelectedListItem, x => ListItems.FirstOrDefault(y => y.Model == x), x => x?.Model ) .AddTo(disposable); SelectedTreeItem .Subscribe(_ => { SelectedListItem.Value = null; touch.CreateListColumns(); touch.CreateListItems(); }) .AddTo(disposable); SelectedListItem .Where(x => x != null) .Subscribe(x => { listItemDisposable.Dispose(); listItemDisposable = new CompositeDisposable(); CompositeDisposable tagDisposable = new CompositeDisposable(); x.Tag .OfType <INotifyPropertyChanged>() .Subscribe(y => { tagDisposable.Dispose(); tagDisposable = new CompositeDisposable(); y.PropertyChangedAsObservable() .Subscribe(_ => touch.UpdateListItem(x.Model)) .AddTo(tagDisposable); }) .AddTo(listItemDisposable); tagDisposable.AddTo(listItemDisposable); }) .AddTo(disposable); SelectedSoundEntry = SelectedListItem .Select(x => x?.Tag.Value as TouchElement.SoundEntry) .Do(_ => SelectedSoundEntry?.Value?.Dispose()) .Select(x => x != null ? new SoundEntryViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedCommandEntry = SelectedListItem .Select(x => x?.Tag.Value as TouchElement.CommandEntry) .Do(_ => SelectedCommandEntry?.Value?.Dispose()) .Select(x => x != null ? new CommandEntryViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); AddSoundEntry = SelectedTreeItem .Select(x => x == TreeItem.Value.Children[0]) .ToReactiveCommand() .WithSubscribe(touch.AddSoundEntry) .AddTo(disposable); AddCommandEntry = SelectedTreeItem .Select(x => x == TreeItem.Value.Children[1]) .ToReactiveCommand() .WithSubscribe(touch.AddCommandEntry) .AddTo(disposable); CopySoundEntry = SelectedSoundEntry .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(touch.CopySoundEntry) .AddTo(disposable); CopyCommandEntry = SelectedCommandEntry .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(touch.CopyCommandEntry) .AddTo(disposable); RemoveSoundEntry = SelectedSoundEntry .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(touch.RemoveSoundEntry) .AddTo(disposable); RemoveCommandEntry = SelectedCommandEntry .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(touch.RemoveCommandEntry) .AddTo(disposable); }
internal TouchElementViewModel(TouchElement touch) { CultureInfo culture = CultureInfo.InvariantCulture; LocationX = touch .ToReactivePropertyAsSynchronized( x => x.LocationX, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); LocationY = touch .ToReactivePropertyAsSynchronized( x => x.LocationY, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); SizeX = touch .ToReactivePropertyAsSynchronized( x => x.SizeX, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.NonNegative, out result, out message); return(message); }) .AddTo(disposable); SizeY = touch .ToReactivePropertyAsSynchronized( x => x.SizeY, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.NonNegative, out result, out message); return(message); }) .AddTo(disposable); JumpScreen = touch .ToReactivePropertyAsSynchronized(x => x.JumpScreen) .AddTo(disposable); SoundIndex = touch .ToReactivePropertyAsSynchronized(x => x.SoundIndex) .AddTo(disposable); CommandInfo = touch .ToReactivePropertyAsSynchronized(x => x.CommandInfo) .AddTo(disposable); CommandOption = touch .ToReactivePropertyAsSynchronized(x => x.CommandOption) .AddTo(disposable); }