public ModePropertiesViewModel(Mode mode) { _editedMode = mode; _originalMode = new Mode(mode); ModeName = _editedMode.ModeName; ModeType = _editedMode.ModeType; Depth = _editedMode.Depth; SourceLevel = _editedMode.SourceLevel; LowFrequency = _editedMode.LowFrequency; HighFrequency = _editedMode.HighFrequency; PulseIntervalString = _editedMode.PulseInterval != null ? ((TimeSpan)_editedMode.PulseInterval).ToString(TimeSpanFormatString) : null; PulseLengthString = _editedMode.PulseLength != null ? ((TimeSpan)_editedMode.PulseLength).ToString(TimeSpanFormatString) : null; HorizontalBeamWidth = _editedMode.HorizontalBeamWidth; VerticalBeamWidth = _editedMode.VerticalBeamWidth; DepressionElevationAngle = _editedMode.DepressionElevationAngle; RelativeBeamAngle = _editedMode.RelativeBeamAngle; MaxPropagationRadius = _editedMode.MaxPropagationRadius; ValidRadialCounts = new List<string> { "Auto", "4", "8", "16", "32", "64", "128" }; RadialCountString = _editedMode.RadialCount == 0 ? ValidRadialCounts[0] : _editedMode.RadialCount.ToString(CultureInfo.InvariantCulture); SideLobeAttenuation = _editedMode.SideLobeAttenuation; AvailableTransmissionLossEngines.AddRange(from key in Globals.PluginManagerService[PluginType.TransmissionLossCalculator].Keys select (TransmissionLossCalculatorPluginBase)Globals.PluginManagerService[PluginType.TransmissionLossCalculator][key].DefaultPlugin); SelectedTransmissionLossEngine = _editedMode.GetTransmissionLossPlugin(Globals.PluginManagerService); _propertyObserver = new PropertyObserver<ModePropertiesViewModel>(this) .RegisterHandler(p => p.SelectedTransmissionLossEngine, () => { }); WindowTitle = string.Format("Mode properties: {0}", _editedMode.ModeName); AddValidationRules( new ValidationRule<ModePropertiesViewModel> { PropertyName = "Depth", Description = "Cannot be negative", IsRuleValid = (target, rule) => target.Depth.HasValue && target.Depth.Value >= 0.0f, } , new ValidationRule<ModePropertiesViewModel> { PropertyName = "SourceLevel", Description = "Must be greater than zero", IsRuleValid = (target, rule) => target.SourceLevel > 0, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "HighFrequency", Description = "Must be greater than zero", IsRuleValid = (target, rule) => target.HighFrequency > 0, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "PulseIntervalString", Description = "Must be a valid, non-negative time span value in the format hh:mm:ss.fff where 00 <= hh <= 23; 00 <= mm <= 59; 00 <= ss <= 59; 000 <= fff <= 999", IsRuleValid = (target, rule) => { if (string.IsNullOrEmpty(target.PulseIntervalString)) return false; TimeSpan timeSpan; var isOK = TimeSpan.TryParseExact(target.PulseIntervalString, TimeSpanFormatString, null, out timeSpan); return isOK && timeSpan.Ticks > 0; }, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "PulseLengthString", Description = "Must be a valid, non-negative time span value in the format hh:mm:ss.fff where 00 <= hh <= 23; 00 <= mm <= 59; 00 <= ss <= 59; 000 <= fff <= 999", IsRuleValid = (target, rule) => { if (string.IsNullOrEmpty(target.PulseLengthString)) return false; TimeSpan timeSpan; var isOK = TimeSpan.TryParseExact(target.PulseLengthString, TimeSpanFormatString, null, out timeSpan); return isOK && timeSpan.Ticks > 0; }, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "RelativeBeamAngle", Description = "Must be between -180 and 180, inclusive", IsRuleValid = (target, rule) => -180 <= target.RelativeBeamAngle && target.RelativeBeamAngle <= 180, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "HorizontalBeamWidth", Description = "Must be a positive value less than or equal to 360", IsRuleValid = (target, rule) => 0 < target.HorizontalBeamWidth && target.HorizontalBeamWidth <= 360, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "VerticalBeamWidth", Description = "Must be a positive value less than or equal to 180", IsRuleValid = (target, rule) => 0 < target.VerticalBeamWidth && target.VerticalBeamWidth <= 180, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "DepressionElevationAngle", Description = "Must be between -90 and 90, inclusive", IsRuleValid = (target, rule) => -90 <= target.DepressionElevationAngle && target.DepressionElevationAngle <= 90, }, new ValidationRule<ModePropertiesViewModel> { PropertyName = "MaxPropagationRadius", Description = "Must be a positive value", IsRuleValid = (target, rule) => target.MaxPropagationRadius > 0, }); }