private static Car ParseCarNode(XElement parent) { Car car; if ((bool)parent.Element("IsMotorCar")) { car = new MotorCar(); } else { car = new TrailerCar(); } car.Mass = (double)parent.Element("Mass"); car.Length = (double)parent.Element("Length"); car.Width = (double)parent.Element("Width"); car.Height = (double)parent.Element("Height"); car.CenterOfGravityHeight = (double)parent.Element("CenterOfGravityHeight"); car.DefinedAxles = (bool)parent.Element("DefinedAxles"); car.FrontAxle = (double)parent.Element("FrontAxle"); car.RearAxle = (double)parent.Element("RearAxle"); car.FrontBogie = ParseBogieNode(parent.Element("FrontBogie")); car.RearBogie = ParseBogieNode(parent.Element("RearBogie")); car.ExposedFrontalArea = (double)parent.Element("ExposedFrontalArea"); car.UnexposedFrontalArea = (double)parent.Element("UnexposedFrontalArea"); car.Performance = ParsePerformanceNode(parent.Element("Performance")); car.Delay = ParseDelayNode(parent.Element("Delay")); car.Move = ParseMoveNode(parent.Element("Move")); car.Brake = ParseBrakeNode(parent.Element("Brake")); car.Pressure = ParsePressureNode(parent.Element("Pressure")); MotorCar motorCar = car as MotorCar; if (motorCar != null) { motorCar.Acceleration = ParseAccelerationNode(parent.Element("Acceleration")); motorCar.Motor = ParseMotorNode(parent.Element("Motor")); } car.Reversed = (bool)parent.Element("Reversed"); car.Object = (string)parent.Element("Object"); car.LoadingSway = (bool)parent.Element("LoadingSway"); return(car); }
internal MotorCarViewModel(MotorCar car, Train train) : base(car) { Acceleration = car .ObserveProperty(x => x.Acceleration) .Do(_ => Acceleration?.Value.Dispose()) .Select(x => new AccelerationViewModel(x, train, car)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); Motor = car .ObserveProperty(x => x.Motor) .Do(_ => Motor?.Value.Dispose()) .Select(x => new MotorViewModel(x)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); }
private static void WriteCarNode(XElement parent, Car car) { XElement carNode = new XElement("Car"); parent.Add(carNode); carNode.Add( new XElement("IsMotorCar", car is MotorCar), new XElement("Mass", car.Mass), new XElement("Length", car.Length), new XElement("Width", car.Width), new XElement("Height", car.Height), new XElement("CenterOfGravityHeight", car.CenterOfGravityHeight), new XElement("DefinedAxles", car.DefinedAxles), new XElement("FrontAxle", car.FrontAxle), new XElement("RearAxle", car.RearAxle) ); WriteBogieNode(carNode, "FrontBogie", car.FrontBogie); WriteBogieNode(carNode, "RearBogie", car.RearBogie); carNode.Add(new XElement("ExposedFrontalArea", car.ExposedFrontalArea)); carNode.Add(new XElement("UnexposedFrontalArea", car.UnexposedFrontalArea)); WritePerformanceNode(carNode, car.Performance); WriteDelayNode(carNode, car.Delay); WriteMoveNode(carNode, car.Move); WriteBrakeNode(carNode, car.Brake); WritePressureNode(carNode, car.Pressure); MotorCar motorCar = car as MotorCar; if (motorCar != null) { WriteAccelerationNode(carNode, motorCar.Acceleration); WriteMotorNode(carNode, motorCar.Motor); } carNode.Add( new XElement("Reversed", car.Reversed), new XElement("Object", car.Object), new XElement("LoadingSway", car.LoadingSway) ); }
internal void ChangeCarClass(int carIndex) { MotorCar motorCar = Train.Cars[carIndex] as MotorCar; TrailerCar trailerCar = Train.Cars[carIndex] as TrailerCar; if (motorCar != null) { Train.Cars[carIndex] = new TrailerCar(motorCar); } if (trailerCar != null) { Train.Cars[carIndex] = new MotorCar(trailerCar); Train.ApplyPowerNotchesToCar(); } Item.Children[1].Children[carIndex].Tag = Train.Cars[carIndex]; OnPropertyChanged(new PropertyChangedEventArgs(nameof(SelectedItem))); }
static void Main() { MotorCar car1 = MotorCar.DesignFromComponents("Bumpy", new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 4), new MotorCar.WindScreen(false)); MotorCar car2 = MotorCar.DesignFromComponents("Wobbly", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 2), new MotorCar.WindScreen(false)); MotorCar car3 = MotorCar.DesignFromComponents("Batty", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(true)); MotorCar car4 = MotorCar.DesignFromComponents("Spiffing", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(false)); Console.WriteLine("Expert opinion on " + car1.Name() + " : \n " + car1.WillItWork()); Console.WriteLine("Expert opinion on " + car2.Name() + " : \n " + car2.WillItWork()); Console.WriteLine("Expert opinion on " + car3.Name() + " : \n " + car3.WillItWork()); Console.WriteLine("Expert opinion on " + car4.Name() + " : \n " + car4.WillItWork()); int count = MotorCar.DesignOpinion.AceDesignCount; int total = MotorCar.DesignOpinion.TotalDesignCount; int percent = MotorCar.DesignOpinion.PercentScore(); Console.WriteLine("Overall opinion rating on car design is " + count + "/" + total + " = " + percent + "%"); Console.WriteLine("Single square wheel thoughts: " + new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 1).Opinion().reason); }
static void Main(string[] args) { MotorCar motorCar = new MotorCar(new Chassis(4, 102, 10.1), new Engine(1200, 1600, 5454), new Transmission("B", "Russia", 5), "Audi"); Truck truck = new Truck(new Chassis(4, 102, 10.1), new Engine(1200, 10, 5454), new Transmission("A", "Russia", 5), 5000); Bus bus = new Bus(new Chassis(4, 102, 10.1), new Engine(1200, 1600, 5454), new Transmission("A", "Russia", 5), 25); Autopark autopark = new Autopark(); autopark.AddAuto(motorCar); autopark.AddAuto(motorCar); autopark.AddAuto(truck); autopark.AddAuto(bus); autopark.PrintInfoCarsSpaceOfEngineMoreThan1500(); autopark.PrintInfoAboutEngineForAllBusesAndTrucks(); autopark.PrintInfoAboutCarsWithIdetnicalTypeTransmission(); }
internal TrainViewModel(Train train, App app) { Handle = train .ObserveProperty(x => x.Handle) .Do(_ => Handle?.Value.Dispose()) .Select(x => new HandleViewModel(x, train)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); Device = train .ObserveProperty(x => x.Device) .Do(_ => Device?.Value.Dispose()) .Select(x => new DeviceViewModel(x, train.Handle)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); Cab = train .ObserveProperty(x => x.Cab) .Do(_ => Cab?.Value.Dispose()) .Select(x => new CabViewModel(x)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); Cars = train.Cars .ToReadOnlyReactiveCollection(x => { MotorCar motorCar = x as MotorCar; TrailerCar trailerCar = x as TrailerCar; CarViewModel viewModel = null; if (motorCar != null) { viewModel = new MotorCarViewModel(motorCar, train); } if (trailerCar != null) { viewModel = new TrailerCarViewModel(trailerCar); } return(viewModel); }) .AddTo(disposable); Couplers = train.Couplers .ToReadOnlyReactiveCollection(x => new CouplerViewModel(x)) .AddTo(disposable); SelectedCar = app .ObserveProperty(x => x.SelectedItem) .Where(x => x != null) .Select(x => Cars.FirstOrDefault(y => y.Model == x.Tag)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedCoupler = app .ObserveProperty(x => x.SelectedItem) .Where(x => x != null) .Select(x => Couplers.FirstOrDefault(y => y.Model == x.Tag)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); }
internal static void Write(string fileName, Train train) { StringBuilder builder = new StringBuilder(); CultureInfo culture = CultureInfo.InvariantCulture; const int n = 15; MotorCar firstMotorCar = train.Cars.OfType <MotorCar>().First(); TrailerCar firstTrailerCar = train.Cars.OfType <TrailerCar>().FirstOrDefault(); builder.AppendLine("OPENBVE" + currentVersion); builder.AppendLine("#ACCELERATION"); for (int i = firstMotorCar.Acceleration.Entries.Count - 1; i >= train.Handle.PowerNotches; i--) { firstMotorCar.Acceleration.Entries.RemoveAt(i); } foreach (Acceleration.Entry entry in firstMotorCar.Acceleration.Entries) { builder.Append(entry.A0.ToString(culture) + ","); builder.Append(entry.A1.ToString(culture) + ","); builder.Append(entry.V1.ToString(culture) + ","); builder.Append(entry.V2.ToString(culture) + ","); builder.AppendLine(entry.E.ToString(culture)); } builder.AppendLine("#PERFORMANCE"); builder.AppendLine($"{firstMotorCar.Performance.Deceleration.ToString(culture).PadRight(n, ' ')}; Deceleration"); builder.AppendLine($"{firstMotorCar.Performance.CoefficientOfStaticFriction.ToString(culture).PadRight(n, ' ')}; CoefficientOfStaticFriction"); builder.AppendLine($"{"0".PadRight(n, ' ')}; Reserved (not used)"); builder.AppendLine($"{firstMotorCar.Performance.CoefficientOfRollingResistance.ToString(culture).PadRight(n, ' ')}; CoefficientOfRollingResistance"); builder.AppendLine($"{firstMotorCar.Performance.AerodynamicDragCoefficient.ToString(culture).PadRight(n, ' ')}; AerodynamicDragCoefficient"); builder.AppendLine("#DELAY"); builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayPower.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayPowerUp"); builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayPower.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayPowerDown"); builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayBrake.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayBrakeUp"); builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayBrake.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayBrakeDown"); builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayLocoBrake.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayLocoBrakeUp (1.5.3.4+)"); builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayLocoBrake.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayLocoBrakeDown (1.5.3.4+)"); builder.AppendLine("#MOVE"); builder.AppendLine($"{firstMotorCar.Move.JerkPowerUp.ToString(culture).PadRight(n, ' ')}; JerkPowerUp"); builder.AppendLine($"{firstMotorCar.Move.JerkPowerDown.ToString(culture).PadRight(n, ' ')}; JerkPowerDown"); builder.AppendLine($"{firstMotorCar.Move.JerkBrakeUp.ToString(culture).PadRight(n, ' ')}; JerkBrakeUp"); builder.AppendLine($"{firstMotorCar.Move.JerkBrakeDown.ToString(culture).PadRight(n, ' ')}; JerkBrakeDown"); builder.AppendLine($"{firstMotorCar.Move.BrakeCylinderUp.ToString(culture).PadRight(n, ' ')}; BrakeCylinderUp"); builder.AppendLine($"{firstMotorCar.Move.BrakeCylinderDown.ToString(culture).PadRight(n, ' ')}; BrakeCylinderDown"); builder.AppendLine("#BRAKE"); builder.AppendLine($"{((int)firstMotorCar.Brake.BrakeType).ToString(culture).PadRight(n, ' ')}; BrakeType"); builder.AppendLine($"{((int)firstMotorCar.Brake.BrakeControlSystem).ToString(culture).PadRight(n, ' ')}; BrakeControlSystem"); builder.AppendLine($"{firstMotorCar.Brake.BrakeControlSpeed.ToString(culture).PadRight(n, ' ')}; BrakeControlSpeed"); builder.AppendLine($"{((int)firstMotorCar.Brake.LocoBrakeType).ToString(culture).PadRight(n, ' ')}; LocoBrakeType (1.5.3.4+)"); builder.AppendLine("#PRESSURE"); builder.AppendLine($"{firstMotorCar.Pressure.BrakeCylinderServiceMaximumPressure.ToString(culture).PadRight(n, ' ')}; BrakeCylinderServiceMaximumPressure"); builder.AppendLine($"{firstMotorCar.Pressure.BrakeCylinderEmergencyMaximumPressure.ToString(culture).PadRight(n, ' ')}; BrakeCylinderEmergencyMaximumPressure"); builder.AppendLine($"{firstMotorCar.Pressure.MainReservoirMinimumPressure.ToString(culture).PadRight(n, ' ')}; MainReservoirMinimumPressure"); builder.AppendLine($"{firstMotorCar.Pressure.MainReservoirMaximumPressure.ToString(culture).PadRight(n, ' ')}; MainReservoirMaximumPressure"); builder.AppendLine($"{firstMotorCar.Pressure.BrakePipeNormalPressure.ToString(culture).PadRight(n, ' ')}; BrakePipeNormalPressure"); builder.AppendLine("#HANDLE"); builder.AppendLine($"{((int)train.Handle.HandleType).ToString(culture).PadRight(n, ' ')}; HandleType"); builder.AppendLine($"{train.Handle.PowerNotches.ToString(culture).PadRight(n, ' ')}; PowerNotches"); builder.AppendLine($"{train.Handle.BrakeNotches.ToString(culture).PadRight(n, ' ')}; BrakeNotches"); builder.AppendLine($"{train.Handle.PowerNotchReduceSteps.ToString(culture).PadRight(n, ' ')}; PowerNotchReduceSteps"); builder.AppendLine($"{((int)train.Handle.HandleBehaviour).ToString(culture).PadRight(n, ' ')}; EbHandleBehaviour (1.5.3.3+)"); builder.AppendLine($"{train.Handle.LocoBrakeNotches.ToString(culture).PadRight(n, ' ')}; LocoBrakeNotches (1.5.3.4+)"); builder.AppendLine($"{((int)train.Handle.LocoBrake).ToString(culture).PadRight(n, ' ')}; LocoBrakeType (1.5.3.4+)"); builder.AppendLine($"{train.Handle.DriverPowerNotches.ToString(culture).PadRight(n, ' ')}; DriverPowerNotches (1.5.3.11+)"); builder.AppendLine($"{train.Handle.DriverBrakeNotches.ToString(culture).PadRight(n, ' ')}; DriverBrakeNotches (1.5.3.11+)"); builder.AppendLine("#CAB"); builder.AppendLine($"{train.Cab.PositionX.ToString(culture).PadRight(n, ' ')}; X"); builder.AppendLine($"{train.Cab.PositionY.ToString(culture).PadRight(n, ' ')}; Y"); builder.AppendLine($"{train.Cab.PositionZ.ToString(culture).PadRight(n, ' ')}; Z"); builder.AppendLine($"{train.Cab.DriverCar.ToString(culture).PadRight(n, ' ')}; DriverCar"); builder.AppendLine("#CAR"); builder.AppendLine($"{firstMotorCar.Mass.ToString(culture).PadRight(n, ' ')}; MotorCarMass"); builder.AppendLine($"{train.Cars.Count(c => c is MotorCar).ToString(culture).PadRight(n, ' ')}; NumberOfMotorCars"); builder.AppendLine($"{(firstTrailerCar ?? new TrailerCar()).Mass.ToString(culture).PadRight(n, ' ')}; TrailerCarMass"); builder.AppendLine($"{train.Cars.Count(c => c is TrailerCar).ToString(culture).PadRight(n, ' ')}; NumberOfTrailerCars"); builder.AppendLine($"{firstMotorCar.Length.ToString(culture).PadRight(n, ' ')}; LengthOfACar"); builder.AppendLine($"{(train.Cars.First() is MotorCar ? "1" : "0").PadRight(n, ' ')}; FrontCarIsAMotorCar"); builder.AppendLine($"{firstMotorCar.Width.ToString(culture).PadRight(n, ' ')}; WidthOfACar"); builder.AppendLine($"{firstMotorCar.Height.ToString(culture).PadRight(n, ' ')}; HeightOfACar"); builder.AppendLine($"{firstMotorCar.CenterOfGravityHeight.ToString(culture).PadRight(n, ' ')}; CenterOfGravityHeight"); builder.AppendLine($"{firstMotorCar.ExposedFrontalArea.ToString(culture).PadRight(n, ' ')}; ExposedFrontalArea"); builder.AppendLine($"{firstMotorCar.UnexposedFrontalArea.ToString(culture).PadRight(n, ' ')}; UnexposedFrontalArea"); builder.AppendLine("#DEVICE"); builder.AppendLine($"{((int)train.Device.Ats).ToString(culture).PadRight(n, ' ')}; Ats"); builder.AppendLine($"{((int)train.Device.Atc).ToString(culture).PadRight(n, ' ')}; Atc"); builder.AppendLine($"{(train.Device.Eb ? "1" : "0").PadRight(n, ' ')}; Eb"); builder.AppendLine($"{(train.Device.ConstSpeed ? "1" : "0").PadRight(n, ' ')}; ConstSpeed"); builder.AppendLine($"{(train.Device.HoldBrake ? "1" : "0").PadRight(n, ' ')}; HoldBrake"); builder.AppendLine($"{((int)train.Device.ReAdhesionDevice).ToString(culture).PadRight(n, ' ')}; ReAdhesionDevice"); builder.AppendLine($"{train.Device.LoadCompensatingDevice.ToString(culture).PadRight(n, ' ')}; Reserved (not used)"); builder.AppendLine($"{((int)train.Device.PassAlarm).ToString(culture).PadRight(n, ' ')}; PassAlarm"); builder.AppendLine($"{((int)train.Device.DoorOpenMode).ToString(culture).PadRight(n, ' ')}; DoorOpenMode"); builder.AppendLine($"{((int)train.Device.DoorCloseMode).ToString(culture).PadRight(n, ' ')}; DoorCloseMode"); builder.AppendLine($"{train.Device.DoorWidth.ToString(culture).PadRight(n, ' ')}; DoorWidth"); builder.AppendLine($"{train.Device.DoorMaxTolerance.ToString(culture).PadRight(n, ' ')}; DoorMaxTolerance"); for (int i = 0; i < 4; i++) { BVEMotorSoundTableEntry[] entries = new BVEMotorSoundTableEntry[0]; switch (i) { case 0: builder.AppendLine("#MOTOR_P1"); entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Power1]); break; case 1: builder.AppendLine("#MOTOR_P2"); entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Power2]); break; case 2: builder.AppendLine("#MOTOR_B1"); entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Brake1]); break; case 3: builder.AppendLine("#MOTOR_B2"); entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Brake2]); break; } int k; for (k = entries.Length - 1; k >= 0; k--) { if (entries[k].SoundIndex >= 0) { break; } } k = Math.Min(k + 2, entries.Length); Array.Resize(ref entries, k); for (int j = 0; j < entries.Length; j++) { builder.Append(entries[j].SoundIndex.ToString(culture) + ","); builder.Append(entries[j].Pitch.ToString(culture) + ","); builder.AppendLine(entries[j].Gain.ToString(culture)); } } File.WriteAllText(fileName, builder.ToString(), new UTF8Encoding(true)); }
internal AccelerationViewModel(Acceleration acceleration, Train train, MotorCar car) { CultureInfo culture = CultureInfo.InvariantCulture; Entries = acceleration.Entries .ToReadOnlyReactiveCollection(x => new EntryViewModel(x)) .AddTo(disposable); SelectedEntryIndex = acceleration .ToReactivePropertyAsSynchronized( x => x.SelectedEntryIndex, ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => x < 0 ? string.Empty : null) .AddTo(disposable); SelectedEntry = SelectedEntryIndex .Select(x => x < 0 ? null : Entries[x]) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); MinVelocity = acceleration .ToReactivePropertyAsSynchronized( x => x.MinVelocity, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .AddTo(disposable); MaxVelocity = acceleration .ToReactivePropertyAsSynchronized( x => x.MaxVelocity, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .AddTo(disposable); MinAcceleration = acceleration .ToReactivePropertyAsSynchronized( x => x.MinAcceleration, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .AddTo(disposable); MaxAcceleration = acceleration .ToReactivePropertyAsSynchronized( x => x.MaxAcceleration, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .AddTo(disposable); NowVelocity = acceleration .ObserveProperty(x => x.NowVelocity) .Select(x => $"{x} km/h") .ToReadOnlyReactivePropertySlim() .AddTo(disposable); NowAcceleration = acceleration .ObserveProperty(x => x.NowAcceleration) .Select(x => $"{x} km/h/s") .ToReadOnlyReactivePropertySlim() .AddTo(disposable); Resistance = acceleration .ToReactivePropertyAsSynchronized(x => x.Resistance) .AddTo(disposable); ImageWidth = acceleration .ToReactivePropertyAsSynchronized( x => x.ImageWidth, ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => x <= 0 ? string.Empty : null) .AddTo(disposable); ImageHeight = acceleration .ToReactivePropertyAsSynchronized( x => x.ImageHeight, ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => x <= 0 ? string.Empty : null) .AddTo(disposable); Image = acceleration .ObserveProperty(x => x.Image) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); new[] { acceleration .PropertyChangedAsObservable() .Where(x => x.PropertyName != nameof(acceleration.NowVelocity) && x.PropertyName != nameof(acceleration.NowAcceleration) && x.PropertyName != nameof(acceleration.Image) ) .OfType <object>(), acceleration.Entries.ObserveElementPropertyChanged().OfType <object>() } .Merge() .ToReadOnlyReactivePropertySlim() .Subscribe(_ => train.DrawAccelerationImage(car)) .AddTo(disposable); ZoomIn = new ReactiveCommand(); ZoomIn.Subscribe(acceleration.ZoomIn).AddTo(disposable); ZoomOut = new ReactiveCommand(); ZoomOut.Subscribe(acceleration.ZoomOut).AddTo(disposable); Reset = new ReactiveCommand(); Reset.Subscribe(acceleration.Reset).AddTo(disposable); MoveLeft = new ReactiveCommand(); MoveLeft.Subscribe(acceleration.MoveLeft).AddTo(disposable); MoveRight = new ReactiveCommand(); MoveRight.Subscribe(acceleration.MoveRight).AddTo(disposable); MoveBottom = new ReactiveCommand(); MoveBottom.Subscribe(acceleration.MoveBottom).AddTo(disposable); MoveTop = new ReactiveCommand(); MoveTop.Subscribe(acceleration.MoveTop).AddTo(disposable); MouseMove = new ReactiveCommand <InputEventModel.EventArgs>(); MouseMove.Subscribe(acceleration.MouseMove).AddTo(disposable); MinVelocity .SetValidateNotifyError(x => { double min; string message; if (Utilities.TryParse(x, NumberRange.NonNegative, out min, out message)) { double max; if (Utilities.TryParse(MaxVelocity.Value, NumberRange.NonNegative, out max) && min >= max) { message = "MinはMax未満でなければなりません。"; } } return(message); }) .Subscribe(_ => MaxVelocity.ForceValidate()) .AddTo(disposable); MinVelocity.ObserveHasErrors .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) .Where(x => !x) .Subscribe(_ => MinVelocity.ForceNotify()) .AddTo(disposable); MaxVelocity .SetValidateNotifyError(x => { double max; string message; if (Utilities.TryParse(x, NumberRange.NonNegative, out max, out message)) { double min; if (Utilities.TryParse(MinVelocity.Value, NumberRange.NonNegative, out min) && max <= min) { message = "MinはMax未満でなければなりません。"; } } return(message); }) .Subscribe(_ => MinVelocity.ForceValidate()) .AddTo(disposable); MaxVelocity.ObserveHasErrors .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) .Where(x => !x) .Subscribe(_ => MaxVelocity.ForceNotify()) .AddTo(disposable); MinAcceleration .SetValidateNotifyError(x => { double min; string message; if (Utilities.TryParse(x, NumberRange.NonNegative, out min, out message)) { double max; if (Utilities.TryParse(MaxAcceleration.Value, NumberRange.NonNegative, out max) && min >= max) { message = "MinはMax未満でなければなりません。"; } } return(message); }) .Subscribe(_ => MaxAcceleration.ForceValidate()) .AddTo(disposable); MinAcceleration.ObserveHasErrors .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) .Where(x => !x) .Subscribe(_ => MinAcceleration.ForceNotify()) .AddTo(disposable); MaxAcceleration .SetValidateNotifyError(x => { double max; string message; if (Utilities.TryParse(x, NumberRange.NonNegative, out max, out message)) { double min; if (Utilities.TryParse(MinAcceleration.Value, NumberRange.NonNegative, out min) && max <= min) { message = "MinはMax未満でなければなりません。"; } } return(message); }) .Subscribe(_ => MinAcceleration.ForceValidate()) .AddTo(disposable); MaxAcceleration.ObserveHasErrors .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) .Where(x => !x) .Subscribe(_ => MaxAcceleration.ForceNotify()) .AddTo(disposable); }