From 0fea2fdab5b6d25ae5ad3e6d7046292e3c0f0c6a Mon Sep 17 00:00:00 2001 From: "VKMTHD\\franzjosefkober" <franz.josef.kober@ivt.tugraz.at> Date: Thu, 7 May 2020 23:45:25 +0200 Subject: [PATCH] added menu to show xml validation errors on relateted textbox and combobox --- .../Converter/SaveButtonLabelConverter.cs | 11 +- .../Helper/Validation/IntegerValidator.cs | 107 ++++++ .../Validation/IntegerValidatorConfig.cs | 79 +++++ VECTO3GUI/Helper/XmlHelper.cs | 6 +- .../AuxiliariesBusComponentData.cs | 28 +- .../TempDataObject/VehicleBusComponentData.cs | 30 +- VECTO3GUI/Resources/GlobalStyles.xaml | 10 +- VECTO3GUI/Util/XML/XMLCompletedBus.cs | 74 ++-- VECTO3GUI/VECTO3GUI.csproj | 14 +- .../ViewModel/Impl/AbstractJobViewModel.cs | 10 +- VECTO3GUI/ViewModel/Impl/AbstractViewModel.cs | 6 +- VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs | 2 +- .../ViewModel/Impl/AuxiliariesViewModel.cs | 30 +- .../Impl/CompleteVehicleBusJobViewModel.cs | 126 ++++++- .../Impl/CompleteVehicleBusViewModel.cs | 26 +- .../ViewModel/Impl/DeclarationJobViewModel.cs | 5 +- .../ViewModel/Impl/EngineOnlyJobViewModel.cs | 7 +- .../Impl/PrimaryVehicleBusJobViewModel.cs | 5 +- .../ViewModel/Impl/ValidatingViewModel.cs | 315 +++++++++--------- VECTO3GUI/ViewModel/Impl/VehicleViewModel.cs | 3 +- .../ViewModel/Interfaces/IAuxiliariesBus.cs | 2 +- .../Interfaces/ICompleteVehicleBus.cs | 2 + .../Interfaces/IComponentViewModel.cs | 9 +- .../ViewModel/Interfaces/IJobEditViewModel.cs | 4 +- .../AuxiliariesDeclarationView.xaml | 99 +++++- .../Declaration/CompleteVehicleBusView.xaml | 303 ++++++++++++++--- .../IntegerVectoParameterControl.xaml | 46 +++ .../IntegerVectoParameterControl.xaml.cs | 181 ++++++++++ VECTO3GUI/Views/JoblistTabView.xaml | 41 ++- 29 files changed, 1269 insertions(+), 312 deletions(-) create mode 100644 VECTO3GUI/Helper/Validation/IntegerValidator.cs create mode 100644 VECTO3GUI/Helper/Validation/IntegerValidatorConfig.cs create mode 100644 VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml create mode 100644 VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml.cs diff --git a/VECTO3GUI/Helper/Converter/SaveButtonLabelConverter.cs b/VECTO3GUI/Helper/Converter/SaveButtonLabelConverter.cs index 7bf7e142c5..39c618a943 100644 --- a/VECTO3GUI/Helper/Converter/SaveButtonLabelConverter.cs +++ b/VECTO3GUI/Helper/Converter/SaveButtonLabelConverter.cs @@ -13,10 +13,19 @@ namespace VECTO3GUI.Helper.Converter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { + var param = parameter as string; + if (param == null) + return value; + + if (value is Component) { var component = (Component)value; - return $"Save {component.GetLabel()} Changes"; + + if (param == "Save") + return $"{param} {component.GetLabel()}"; + if (param == "Commit") + return $"{param} {component.GetLabel()} changes"; } return value; diff --git a/VECTO3GUI/Helper/Validation/IntegerValidator.cs b/VECTO3GUI/Helper/Validation/IntegerValidator.cs new file mode 100644 index 0000000000..86c43ebb05 --- /dev/null +++ b/VECTO3GUI/Helper/Validation/IntegerValidator.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Windows.Controls; +using System.Windows.Data; +using VECTO3GUI.ViewModel.Impl; +using VECTO3GUI.Views.CustomControls; + +namespace VECTO3GUI.Helper.Validation +{ + public class IntegerValidator : ValidationRule + { + private IntegerValidatorConfig _integerValidator; + + public int MinValue { get; set; } + public int MaxValue { get; set; } + public bool ValidateInput { get; set; } + + + public IntegerValidator() + { + + } + + public IntegerValidatorConfig ValidatorConfig + { + get { return _integerValidator; } + set + { + _integerValidator = value; + value?.SetValidator(this); + } + } + + //public override ValidationResult Validate(object value, CultureInfo cultureInfo, BindingExpressionBase owner) + //{ + // var validateResult = base.Validate(value, cultureInfo, owner); + + // var dataItem = ((IntegerVectoParameterControl)((BindingExpression)owner).DataItem); + + + // if (dataItem.DataContext is CompleteVehicleBusViewModel) { + + // } + + + + + // //var exp = ((IntegerVectoParameterControl)((BindingExpression)owner).DataItem).Caption; + + + // //var t = ((IntegerVectoParameterControl)((BindingExpression)owner).ResolvedSource) .DataContext as CompleteVehicleBusViewModel; + // //t.InputValidationErrors = !validateResult.IsValid; + + // return validateResult; + + //} + + public override ValidationResult Validate(object value, CultureInfo cultureInfo) + { + + + var strValue = value as string; + int number; + + if(!int.TryParse(strValue, out number)) + return new ValidationResult(false, "Not a valid integer value!"); + + if (!ValidateInput) + return ValidationResult.ValidResult; + + + if (number < MinValue) + return new ValidationResult(false, $"Only integer values greater than or equals to {MinValue} are allowed!"); + + if(number > MaxValue) + return new ValidationResult(false, $"Only integer values less than or equals to {MaxValue} are allowed!"); + + return ValidationResult.ValidResult; + } + + private void SetPropertyError(bool validationResult, string propertyName) + { + + + } + + + + + //protected void SetChangedProperty(bool changed, [CallerMemberName] string propertyName = "") + //{ + // if (!changed) + // { + // if (_changedInput.Contains(propertyName)) + // _changedInput.Remove(propertyName); + // } + // else + // { + // if (!_changedInput.Contains(propertyName)) + // _changedInput.Add(propertyName); + // } + + // UnsavedChanges = _changedInput.Count > 0; + //} + } +} diff --git a/VECTO3GUI/Helper/Validation/IntegerValidatorConfig.cs b/VECTO3GUI/Helper/Validation/IntegerValidatorConfig.cs new file mode 100644 index 0000000000..b344835237 --- /dev/null +++ b/VECTO3GUI/Helper/Validation/IntegerValidatorConfig.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using TUGraz.VectoCommon.Utils; + +namespace VECTO3GUI.Helper.Validation +{ + public class IntegerValidatorConfig : Freezable + { + public int MinValue + { + get { return (int)GetValue(MinValueProperty); } + set { SetValue(MinValueProperty, value); } + } + + public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register( + nameof(MinValue), typeof(int), typeof(IntegerValidatorConfig), new FrameworkPropertyMetadata(MinPropertyChangedCallback)); + + + private static void MinPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var integerValidator = (IntegerValidatorConfig)d; + if (integerValidator.Validator != null) + integerValidator.Validator.MinValue = (int)e.NewValue; + } + + public int MaxValue + { + get { return (int)GetValue(MaxValueProperty); } + set { SetValue(MaxValueProperty, value); } + } + + public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register( + nameof(MaxValue), typeof(int), typeof(IntegerValidatorConfig), new FrameworkPropertyMetadata(MaxPropertyChangedCallback)); + + private static void MaxPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var integerValidator = (IntegerValidatorConfig)d; + if (integerValidator.Validator != null) + integerValidator.Validator.MaxValue = (int)e.NewValue; + } + + public bool ValidateInput + { + get { return (bool)GetValue(ValidateInputProperty); } + set { SetValue(ValidateInputProperty, value); } + } + + public static readonly DependencyProperty ValidateInputProperty = DependencyProperty.Register( + nameof(ValidateInput), typeof(bool), typeof(IntegerValidatorConfig), new FrameworkPropertyMetadata(ValidateInputPropertyChangedCallback)); + + private static void ValidateInputPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var integerValidator = (IntegerValidatorConfig)d; + if (integerValidator.Validator != null) + integerValidator.Validator.ValidateInput = (bool)e.NewValue; + } + + + private IntegerValidator Validator { get; set; } + + public void SetValidator(IntegerValidator validator) + { + Validator = validator; + if (validator != null) { + validator.MaxValue = MaxValue; + validator.MinValue = MinValue; + } + } + + protected override Freezable CreateInstanceCore() + { + return new IntegerValidatorConfig(); + } + } +} diff --git a/VECTO3GUI/Helper/XmlHelper.cs b/VECTO3GUI/Helper/XmlHelper.cs index 3b5cf49f43..f27991b36e 100644 --- a/VECTO3GUI/Helper/XmlHelper.cs +++ b/VECTO3GUI/Helper/XmlHelper.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; +using System.Xml.Schema; using Castle.Core.Internal; using Microsoft.WindowsAPICodePack.Shell.PropertySystem; using TUGraz.VectoCommon.Exceptions; @@ -38,7 +39,8 @@ namespace VECTO3GUI.Helper return xmlDocument.SelectNodes($"//*[local-name()='{parentNode}']//*[local-name()='{nodeName}']"); } - public static bool ValidateXDocument(XDocument xDocument) + public static bool ValidateXDocument(XDocument xDocument, Action<bool> resultAction = null, + Action<XmlSeverityType, ValidationEvent> validationErrorAction = null) { var xmlDocument = xDocument.ToXmlDocument(); if (xmlDocument == null) @@ -50,7 +52,7 @@ namespace VECTO3GUI.Helper throw new VectoException("unknown xml file! {0}", xmlDocument.DocumentElement.LocalName); } - var validator = new XMLValidator(xmlDocument, null, XMLValidator.CallBackExceptionOnError); + var validator = new XMLValidator(xmlDocument, resultAction, validationErrorAction); return validator.ValidateXML(documentType.Value); ; } diff --git a/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs b/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs index 72382e5a17..9779826438 100644 --- a/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs +++ b/VECTO3GUI/Model/TempDataObject/AuxiliariesBusComponentData.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using TUGraz.VectoCommon.BusAuxiliaries; +using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; using VECTO3GUI.Helper; using VECTO3GUI.ViewModel.Interfaces; @@ -32,7 +33,7 @@ namespace VECTO3GUI.Model.TempDataObject public bool HeatPump { get; set; } public bool AdjustableAuxiliaryHeater { get; set; } public bool SeparateAirDistributionDucts { get; set; } - public ConsumerTechnology DoorDriveTechnology { get; set; } + public Dictionary<string, string> XmlNamesToPropertyMapping { get; private set; } #endregion @@ -41,11 +42,14 @@ namespace VECTO3GUI.Model.TempDataObject AlternatorTechnologies = new ObservableCollectionEx<AlternatorTechnologyModel>(); if (defaultValues) ClearValues(viewModel); + SetXmlNamesToPropertyMapping(); } public AuxiliariesBusComponentData(IAuxiliariesViewModel viewModel) { + AlternatorTechnologies = new ObservableCollectionEx<AlternatorTechnologyModel>(); SetValues(viewModel); + SetXmlNamesToPropertyMapping(); } public void UpdateCurrentValues(IAuxiliariesViewModel viewModel) @@ -74,6 +78,8 @@ namespace VECTO3GUI.Model.TempDataObject private void SetAlternatorTechnology(ObservableCollectionEx<AlternatorTechnologyModel> res) { + if (OriginAlternatorTechnologies == null) + return; //var res = new ObservableCollectionEx<AlternatorTechnologyModel>(); res.Clear(); for (int i = 0; i < OriginAlternatorTechnologies.Count; i++) { @@ -134,5 +140,25 @@ namespace VECTO3GUI.Model.TempDataObject } return result; } + + private void SetXmlNamesToPropertyMapping() + { + XmlNamesToPropertyMapping = new Dictionary<string, string> { + {XMLNames.BusAux_ElectricSystem, nameof(AlternatorTechnologies)}, + {XMLNames.Bus_Dayrunninglights, nameof(DayrunninglightsLED)}, + {XMLNames.Bus_Headlights, nameof(HeadlightsLED)}, + {XMLNames.Bus_Positionlights, nameof(PositionlightsLED)}, + {XMLNames.Bus_Brakelights, nameof(BrakelightsLED)}, + {XMLNames.Bus_Interiorlights, nameof(InteriorLightsLED)}, + {XMLNames.Bus_SystemConfiguration, nameof(SystemConfiguration)}, + {XMLNames.Bus_DriverAC, nameof(CompressorTypeDriver)}, + {XMLNames.Bus_PassengerAC, nameof(CompressorTypePassenger)}, + {XMLNames.Bus_AuxiliaryHeaterPower, nameof(AuxHeaterPower)}, + {XMLNames.Bus_DoubleGlasing, nameof(DoubleGlasing)}, + {XMLNames.Bus_HeatPump, nameof(HeatPump)}, + {XMLNames.Bus_AdjustableAuxiliaryHeater, nameof(AdjustableAuxiliaryHeater)}, + {XMLNames.Bus_SeparateAirDistributionDucts, nameof(SeparateAirDistributionDucts)}, + }; + } } } diff --git a/VECTO3GUI/Model/TempDataObject/VehicleBusComponentData.cs b/VECTO3GUI/Model/TempDataObject/VehicleBusComponentData.cs index 6746a570b2..798dd16408 100644 --- a/VECTO3GUI/Model/TempDataObject/VehicleBusComponentData.cs +++ b/VECTO3GUI/Model/TempDataObject/VehicleBusComponentData.cs @@ -7,8 +7,8 @@ using System.Threading.Tasks; using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; -using VECTO3GUI.ViewModel.Impl; using VECTO3GUI.ViewModel.Interfaces; namespace VECTO3GUI.Model.TempDataObject @@ -38,6 +38,7 @@ namespace VECTO3GUI.Model.TempDataObject public Meter VehicleWidth { get; set; } public Meter EntranceHeight { get; set; } public ConsumerTechnology DoorDriveTechnology { get; set; } + public Dictionary<string, string> XmlNamesToPropertyMapping { get; private set; } #endregion @@ -45,6 +46,7 @@ namespace VECTO3GUI.Model.TempDataObject { if(defaultValues) ClearValues(viewModel); + SetXmlNamesToPropertyMapping(); } public VehicleBusComponentData(ICompleteVehicleBusViewModel viewModel) @@ -127,5 +129,31 @@ namespace VECTO3GUI.Model.TempDataObject DoorDriveTechnology = vehicleBus.DoorDriveTechnology; } + private void SetXmlNamesToPropertyMapping() + { + XmlNamesToPropertyMapping = new Dictionary<string, string> { + {XMLNames.Component_Manufacturer, nameof(Manufacturer)}, + {XMLNames.Component_ManufacturerAddress, nameof(ManufacturerAddress)}, + {XMLNames.Component_Model, nameof(Model)}, + {XMLNames.Vehicle_VIN, nameof(VIN)}, + {XMLNames.Component_Date, nameof(Date)}, + {XMLNames.Vehicle_LegislativeClass, nameof(LegislativeClass)}, + {XMLNames.Vehicle_RegisteredClass, nameof(RegisteredClass)}, + {XMLNames.Vehicle_VehicleCode, nameof(VehicleCode)}, + {XMLNames.Vehicle_CurbMassChassis, nameof(CurbMassChassis)}, + {XMLNames.TPMLM, nameof(TechnicalPermissibleMaximumLadenMass)}, + {XMLNames.Vehicle_NgTankSystem, nameof(NgTankSystem)}, + {XMLNames.Bus_LowerDeck, nameof(NumberOfPassengersLowerDeck)}, + {XMLNames.Bus_UpperDeck, nameof(NumberOfPassengersUpperDeck)}, + {XMLNames.Bus_LowEntry, nameof(LowEntry)}, + {XMLNames.Bus_HeighIntegratedBody, nameof(HeightIntegratedBody)}, + {XMLNames.Bus_VehicleLength, nameof(VehicleLength)}, + {XMLNames.Bus_VehicleWidth, nameof(VehicleWidth)}, + {XMLNames.Bus_EntranceHeight, nameof(EntranceHeight)}, + {XMLNames.BusAux_PneumaticSystem_DoorDriveTechnology, nameof(DoorDriveTechnology)} + }; + } + + } } diff --git a/VECTO3GUI/Resources/GlobalStyles.xaml b/VECTO3GUI/Resources/GlobalStyles.xaml index 169b5b069a..1e1652296d 100644 --- a/VECTO3GUI/Resources/GlobalStyles.xaml +++ b/VECTO3GUI/Resources/GlobalStyles.xaml @@ -1,6 +1,7 @@ <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"> + xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:helper="clr-namespace:VECTO3GUI.Helper"> <Style TargetType="{x:Type DataGridColumnHeadersPresenter}" > <Setter Property="Template"> @@ -56,7 +57,7 @@ <Setter Property="VerticalAlignment" Value="Center"/> </Style> - <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}" BasedOn="{StaticResource MetroTextBox}"> + <!--<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}" BasedOn="{StaticResource MetroTextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" @@ -64,5 +65,8 @@ Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> - </Style> + </Style>--> + + + </ResourceDictionary> \ No newline at end of file diff --git a/VECTO3GUI/Util/XML/XMLCompletedBus.cs b/VECTO3GUI/Util/XML/XMLCompletedBus.cs index fe7fbb1e3b..9b2a7730e3 100644 --- a/VECTO3GUI/Util/XML/XMLCompletedBus.cs +++ b/VECTO3GUI/Util/XML/XMLCompletedBus.cs @@ -82,32 +82,32 @@ namespace VECTO3GUI.Util.XML new XAttribute(_xsi + "type", XMLDeclarationCompletedBusDataProviderV26.XSD_TYPE),// "CompletedVehicleDeclarationType" new XAttribute("xmlns", _v26), - new XElement(_v26 + XMLNames.Component_Manufacturer, vehicleData.Manufacturer), + new XElement(_v26 + XMLNames.Component_Manufacturer, vehicleData?.Manufacturer), new XElement(_v26 + XMLNames.Component_ManufacturerAddress, vehicleData?.ManufacturerAddress), - new XElement(_v26 + XMLNames.Component_Model, vehicleData.Model), - new XElement(_v26 + XMLNames.Vehicle_VIN, vehicleData.VIN), + new XElement(_v26 + XMLNames.Component_Model, vehicleData?.Model), + new XElement(_v26 + XMLNames.Vehicle_VIN, vehicleData?.VIN), new XElement(_v26 + XMLNames.Component_Date, XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)), - new XElement(_v26 + XMLNames.Vehicle_LegislativeClass, vehicleData.LegislativeClass.GetLabel()), - new XElement(_v26 + XMLNames.Vehicle_RegisteredClass, vehicleData.RegisteredClass.GetLabel()), - new XElement(_v26 + XMLNames.Vehicle_VehicleCode, vehicleData.VehicleCode.GetLabel()), - new XElement(_v26 + XMLNames.Vehicle_CurbMassChassis, vehicleData.CurbMassChassis.ToXMLFormat(0)), - new XElement(_v26 + XMLNames.TPMLM, vehicleData.TechnicalPermissibleMaximumLadenMass.ToXMLFormat(0)), - vehicleData.NgTankSystem == null ? null : new XElement(_v26 + XMLNames.Vehicle_NgTankSystem, vehicleData.NgTankSystem), + new XElement(_v26 + XMLNames.Vehicle_LegislativeClass, vehicleData?.LegislativeClass.GetLabel()), + new XElement(_v26 + XMLNames.Vehicle_RegisteredClass, vehicleData?.RegisteredClass.GetLabel()), + new XElement(_v26 + XMLNames.Vehicle_VehicleCode, vehicleData?.VehicleCode.GetLabel()), + new XElement(_v26 + XMLNames.Vehicle_CurbMassChassis, vehicleData?.CurbMassChassis?.ToXMLFormat(0)), + new XElement(_v26 + XMLNames.TPMLM, vehicleData?.TechnicalPermissibleMaximumLadenMass?.ToXMLFormat(0)), + vehicleData?.NgTankSystem == null ? null : new XElement(_v26 + XMLNames.Vehicle_NgTankSystem, vehicleData?.NgTankSystem), new XElement(_v26 + "RegisteredPassengers", - new XElement(_v26 + XMLNames.Bus_LowerDeck, vehicleData.NumberOfPassengersLowerDeck), - new XElement(_v26 + XMLNames.Bus_UpperDeck, vehicleData.NumberOfPassengersUpperDeck) + new XElement(_v26 + XMLNames.Bus_LowerDeck, vehicleData?.NumberOfPassengersLowerDeck), + new XElement(_v26 + XMLNames.Bus_UpperDeck, vehicleData?.NumberOfPassengersUpperDeck) ), - new XElement(_v26 + XMLNames.Bus_LowEntry, vehicleData.LowEntry), - new XElement(_v26 + XMLNames.Bus_HeighIntegratedBody, vehicleData.HeightIntegratedBody.ToXMLFormat(3)), - new XElement(_v26 + XMLNames.Bus_VehicleLength, vehicleData.VehicleLength.ToXMLFormat(3)), - new XElement(_v26 + XMLNames.Bus_VehicleWidth, vehicleData.VehicleWidth.ToXMLFormat(3)), - new XElement(_v26 + XMLNames.Bus_EntranceHeight, vehicleData.EntranceHeight.ToXMLFormat(3)), - new XElement(_v26 + XMLNames.BusAux_PneumaticSystem_DoorDriveTechnology, vehicleData.DoorDriveTechnology.GetLabel().ToLower()), - - new XElement(_v26 + XMLNames.Vehicle_Components, - new XAttribute(_xsi + "type", XMLDeclarationCompleteBusComponentsDataProviderV26.XSD_TYPE),//"CompletedVehicleComponentsDeclarationType" - GetComponentXElements(inputData) - ) + new XElement(_v26 + XMLNames.Bus_LowEntry, vehicleData?.LowEntry), + new XElement(_v26 + XMLNames.Bus_HeighIntegratedBody, vehicleData?.HeightIntegratedBody?.ToXMLFormat(3)), + new XElement(_v26 + XMLNames.Bus_VehicleLength, vehicleData?.VehicleLength?.ToXMLFormat(3)), + new XElement(_v26 + XMLNames.Bus_VehicleWidth, vehicleData?.VehicleWidth?.ToXMLFormat(3)), + new XElement(_v26 + XMLNames.Bus_EntranceHeight, vehicleData?.EntranceHeight?.ToXMLFormat(3)), + new XElement(_v26 + XMLNames.BusAux_PneumaticSystem_DoorDriveTechnology, vehicleData?.DoorDriveTechnology.GetLabel()?.ToLower()), + + new XElement(_v26 + XMLNames.Vehicle_Components, + new XAttribute(_xsi + "type", XMLDeclarationCompleteBusComponentsDataProviderV26.XSD_TYPE),//"CompletedVehicleComponentsDeclarationType" + GetComponentXElements(inputData) + ) ); } @@ -134,30 +134,30 @@ namespace VECTO3GUI.Util.XML new XAttribute("xmlns", _v20), new XElement(_v20 + XMLNames.ComponentDataWrapper, - new XAttribute(XMLNames.Component_ID_Attr, airdrag.DigestValue.Reference.Replace("#","")), + new XAttribute(XMLNames.Component_ID_Attr, airdrag?.DigestValue.Reference.Replace("#","")), new XAttribute(_xsi + "type", XMLDeclarationAirdragDataProviderV10.XSD_TYPE), // "AirDragDataDeclarationType" - new XElement(_v20 + XMLNames.Component_Manufacturer, airdrag.Manufacturer), - new XElement(_v20 + XMLNames.Component_Model, airdrag.Model), - new XElement(_v20 + XMLNames.Component_CertificationNumber, airdrag.CertificationNumber), - new XElement(_v20 + XMLNames.Component_Date, airdrag.Date), - new XElement(_v20 + XMLNames.Component_AppVersion, airdrag.AppVersion), - new XElement(_v20 + "CdxA_0", airdrag.CdxA_0.ToXMLFormat()), - new XElement(_v20 + "TransferredCdxA", airdrag.TransferredCdxA.ToXMLFormat()), - new XElement(_v20 + XMLNames.AirDrag_DeclaredCdxA, airdrag.DeclaredCdxA.ToXMLFormat())), + new XElement(_v20 + XMLNames.Component_Manufacturer, airdrag?.Manufacturer), + new XElement(_v20 + XMLNames.Component_Model, airdrag?.Model), + new XElement(_v20 + XMLNames.Component_CertificationNumber, airdrag?.CertificationNumber), + new XElement(_v20 + XMLNames.Component_Date, airdrag?.Date), + new XElement(_v20 + XMLNames.Component_AppVersion, airdrag?.AppVersion), + new XElement(_v20 + "CdxA_0", airdrag?.CdxA_0.ToXMLFormat()), + new XElement(_v20 + "TransferredCdxA", airdrag?.TransferredCdxA.ToXMLFormat()), + new XElement(_v20 + XMLNames.AirDrag_DeclaredCdxA, airdrag?.DeclaredCdxA.ToXMLFormat())), new XElement(_v20 + XMLNames.DI_Signature, new XElement(_di +XMLNames.DI_Signature_Reference, - new XAttribute(XMLNames.DI_Signature_Reference_URI_Attr, airdrag.DigestValue.Reference), + new XAttribute(XMLNames.DI_Signature_Reference_URI_Attr, airdrag?.DigestValue.Reference), new XElement(_di + XMLNames.DI_Signature_Reference_Transforms, new XElement(_di + XMLNames.DI_Signature_Reference_Transforms_Transform, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, airdrag.DigestValue.CanonicalizationMethods[0])), + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, airdrag?.DigestValue.CanonicalizationMethods[0])), new XElement(_di + XMLNames.DI_Signature_Reference_Transforms_Transform, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, airdrag.DigestValue.CanonicalizationMethods[1])) + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, airdrag?.DigestValue.CanonicalizationMethods[1])) ), new XElement(_di + XMLNames.DI_Signature_Reference_DigestMethod, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, airdrag.DigestValue.DigestMethod)), - new XElement(_di + XMLNames.DI_Signature_Reference_DigestValue, airdrag.DigestValue.DigestValue)) + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, airdrag?.DigestValue.DigestMethod)), + new XElement(_di + XMLNames.DI_Signature_Reference_DigestValue, airdrag?.DigestValue.DigestValue)) ) ); } @@ -181,7 +181,7 @@ namespace VECTO3GUI.Util.XML new XElement(_v26 + XMLNames.Bus_CompressorType, new XElement(_v26 + XMLNames.Bus_DriverAC, auxBus?.CompressorTypeDriver.GetLabel()), new XElement(_v26 + XMLNames.Bus_PassengerAC, auxBus?.CompressorTypePassenger.GetLabel())), - new XElement(_v26 + XMLNames.Bus_AuxiliaryHeaterPower, Convert.ToInt32(auxBus?.AuxHeaterPower.Value())), + new XElement(_v26 + XMLNames.Bus_AuxiliaryHeaterPower, Convert.ToInt32(auxBus?.AuxHeaterPower?.Value())), new XElement(_v26 + XMLNames.Bus_DoubleGlasing, auxBus?.DoubleGlasing), new XElement(_v26 + XMLNames.Bus_HeatPump, auxBus?.HeatPump), new XElement(_v26 + XMLNames.Bus_AdjustableAuxiliaryHeater, auxBus?.AdjustableAuxiliaryHeater), diff --git a/VECTO3GUI/VECTO3GUI.csproj b/VECTO3GUI/VECTO3GUI.csproj index cc8bb460cf..751c6943d1 100644 --- a/VECTO3GUI/VECTO3GUI.csproj +++ b/VECTO3GUI/VECTO3GUI.csproj @@ -174,6 +174,8 @@ <Compile Include="Helper\Converter\SaveButtonLabelConverter.cs" /> <Compile Include="Helper\SerializeHelper.cs" /> <Compile Include="Helper\TextBoxInputRegExBehaviour.cs" /> + <Compile Include="Helper\Validation\IntegerValidatorConfig.cs" /> + <Compile Include="Helper\Validation\IntegerValidator.cs" /> <Compile Include="Helper\ViewModelBase.cs" /> <Compile Include="Helper\XmlComponentReaderHelper.cs" /> <Compile Include="Helper\XmlHelper.cs" /> @@ -374,6 +376,9 @@ <Compile Include="Views\CustomControls\CommonDeclarationComponentData.xaml.cs"> <DependentUpon>CommonDeclarationComponentData.xaml</DependentUpon> </Compile> + <Compile Include="Views\CustomControls\IntegerVectoParameterControl.xaml.cs"> + <DependentUpon>IntegerVectoParameterControl.xaml</DependentUpon> + </Compile> <Compile Include="Views\CustomControls\VectoParameterControl.xaml.cs"> <DependentUpon>VectoParameterControl.xaml</DependentUpon> </Compile> @@ -563,6 +568,10 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> + <Page Include="Views\CustomControls\IntegerVectoParameterControl.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\CustomControls\VectoParameterControl.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -630,8 +639,11 @@ </ProjectReference> </ItemGroup> <ItemGroup> - <Resource Include="Resources\AirdragLoadTestFile.xml" /> + <Resource Include="Resources\AirdragLoadTestFile.xml"> + <SubType>Designer</SubType> + </Resource> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs index 484e89205a..10e435154f 100644 --- a/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/AbstractJobViewModel.cs @@ -22,7 +22,7 @@ namespace VECTO3GUI.ViewModel.Impl private IComponentViewModel _currentComponent; private ICommand _saveJobCommand; private ICommand _closeJobCommand; - private ICommand _saveToJobCommand; + private ICommand _saveAsJobCommand; protected string XmlFilePath { get; private set; } @@ -69,15 +69,15 @@ namespace VECTO3GUI.ViewModel.Impl protected abstract void DoCloseJob(Window window); - public ICommand SaveToJob + public ICommand SaveAsJob { - get { return _saveToJobCommand ?? (_saveToJobCommand = new RelayCommand<Window>(DoSaveToJob, CanSaveToJob)); } + get { return _saveAsJobCommand ?? (_saveAsJobCommand = new RelayCommand<Window>(DoSaveAsJob, CanSaveAsJob)); } } - protected virtual bool CanSaveToJob(Window window) + protected virtual bool CanSaveAsJob(Window window) { return true; } - protected abstract void DoSaveToJob(Window window); + protected abstract void DoSaveAsJob(Window window); public ICommand EditComponent diff --git a/VECTO3GUI/ViewModel/Impl/AbstractViewModel.cs b/VECTO3GUI/ViewModel/Impl/AbstractViewModel.cs index 3c2880ce51..802679acdd 100644 --- a/VECTO3GUI/ViewModel/Impl/AbstractViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/AbstractViewModel.cs @@ -72,11 +72,15 @@ namespace VECTO3GUI.ViewModel.Impl public virtual void ResetComponentData() {} - public virtual object SaveComponentData() + public virtual object CommitComponentData() { return null; } + public virtual void ShowValidationError(Dictionary<string, string> errors) + { + } + #region Submodule Handling protected IEnumerable<Component> GetSubmodels() { diff --git a/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs b/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs index 614dccd1f5..568df271ae 100644 --- a/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/AirdragViewModel.cs @@ -276,7 +276,7 @@ namespace VECTO3GUI.ViewModel.Impl _componentData.ResetToComponentValues(this); } - public override object SaveComponentData() + public override object CommitComponentData() { _componentData.UpdateCurrentValues(this); ClearChangedProperties(); diff --git a/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs b/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs index 9cc5a9fff6..bc444973a3 100644 --- a/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/AuxiliariesViewModel.cs @@ -139,7 +139,7 @@ namespace VECTO3GUI.ViewModel.Impl public ObservableCollectionEx<AlternatorTechnologyModel> AlternatorTechnologies { get { return _alternatorTechnologies; } - //set { SetProperty(ref _alternatorTechnologies, value); } + set { SetProperty(ref _alternatorTechnologies, value); } } public bool DayrunninglightsLED @@ -286,6 +286,8 @@ namespace VECTO3GUI.ViewModel.Impl } } + public Dictionary<string, string> XmlNamesToPropertyMapping { get; private set; } + public ConsumerTechnology DoorDriveTechnology { get; set; } @@ -311,6 +313,7 @@ namespace VECTO3GUI.ViewModel.Impl SetBusAuxiliaryValues(_busAuxiliaries); SetAllowedValues(); + XmlNamesToPropertyMapping = _componentData.XmlNamesToPropertyMapping; //ConnectAxleViewModel(); } @@ -325,6 +328,7 @@ namespace VECTO3GUI.ViewModel.Impl if (!busAux.ElectricSupply.Alternators.IsNullOrEmpty()) { + AlternatorTechnologies.Clear(); // = new ObservableCollectionEx<AlternatorTechnologyModel>(); AlternatorTechnologies.CollectionChanged += AlternatorTechnologiesOnCollectionChanged; @@ -414,12 +418,28 @@ namespace VECTO3GUI.ViewModel.Impl SetChangedProperty(changed, nameof(AlternatorTechnologies)); } - public override object SaveComponentData() + public override object CommitComponentData() { _componentData.UpdateCurrentValues(this); ClearChangedProperties(); return _componentData; } + public override void ShowValidationError(Dictionary<string, string> errors) + { + if (errors.IsNullOrEmpty()) + return; + + foreach (var error in errors) + { + string propertyName; + if (XmlNamesToPropertyMapping.TryGetValue(error.Key, out propertyName)) + { + AddPropertyError(propertyName, error.Value); + } + } + } + + #region Commands @@ -463,6 +483,12 @@ namespace VECTO3GUI.ViewModel.Impl private void DoAddAlternator() { + if (AlternatorTechnologies == null) { + AlternatorTechnologies = new ObservableCollectionEx<AlternatorTechnologyModel>(); + AlternatorTechnologies.CollectionChanged += AlternatorTechnologiesOnCollectionChanged; + AlternatorTechnologies.CollectionItemChanged += AlternatorTechnologiesOnCollectionItemChanged; + } + AlternatorTechnologies.Add(new AlternatorTechnologyModel { AlternatorTechnology = string.Empty diff --git a/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs index ccae3e6231..1309953ef7 100644 --- a/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusJobViewModel.cs @@ -5,14 +5,18 @@ using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using System.Xml; +using System.Xml.Schema; using MahApps.Metro.Controls.Dialogs; using Ninject; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCore.OutputData.XML.DeclarationJobs; +using TUGraz.VectoCore.Utils; using VECTO3GUI.Helper; using VECTO3GUI.ViewModel.Interfaces; using VECTO3GUI.Util; using VECTO3GUI.Util.XML; +using Component = VECTO3GUI.Util.Component; namespace VECTO3GUI.ViewModel.Impl @@ -24,8 +28,15 @@ namespace VECTO3GUI.ViewModel.Impl private readonly XMLCompletedBus _xmlCompletedBus; private readonly XMLCompletedBusWriter _xmlCompletedBusWriter; - private ICommand _saveComponentCommand; private ICommand _resetComponentCommand; + private ICommand _commitComponentCommand; + + private bool _saveAsButtonVisible; + private bool _saveButtonVisibility; + + private Dictionary<string, string> _errors; + private ICommand _validateInputCommand; + private ICommand _validationErrorsCommand; #endregion @@ -33,6 +44,17 @@ namespace VECTO3GUI.ViewModel.Impl public Dictionary<Component, object> CompleteVehicleBusData { get; private set; } + public bool SaveAsButtonVisible + { + get { return _saveAsButtonVisible; } + set { SetProperty(ref _saveAsButtonVisible, value); } + } + + public bool SaveButtonVisibility + { + get { return _saveButtonVisibility; } + set { SetProperty(ref _saveButtonVisibility, value); } + } #endregion public CompleteVehicleBusJobViewModel(IKernel kernel, IDeclarationInputDataProvider inputData) @@ -50,9 +72,18 @@ namespace VECTO3GUI.ViewModel.Impl _xmlCompletedBus = new XMLCompletedBus(); _xmlCompletedBusWriter = new XMLCompletedBusWriter(); - } + SetVisibilityOfSaveButtons(); + + _errors = new Dictionary<string, string>(); + } + private void SetVisibilityOfSaveButtons() + { + SaveAsButtonVisible = IsNewJob; + SaveButtonVisibility = !IsNewJob; + } + #region Commands protected override bool CanSaveJob(Window window) @@ -77,13 +108,18 @@ namespace VECTO3GUI.ViewModel.Impl SetCurrentDataToSave(); var xDoc = _xmlCompletedBus.GenerateCompletedBusDocument(CompleteVehicleBusData); - if (XmlHelper.ValidateXDocument(xDoc)) { + if (XmlHelper.ValidateXDocument(xDoc, null, ValidationErrorAction)) { _xmlCompletedBusWriter.WriteCompletedBusXml(XmlFilePath, xDoc); CloseWindow(window); } + } } + + + + protected override void DoCloseJob(Window window) { if (CloseWindowDialog()) { @@ -91,7 +127,7 @@ namespace VECTO3GUI.ViewModel.Impl } } - protected override void DoSaveToJob(Window window) + protected override void DoSaveAsJob(Window window) { var filePath = FileDialogHelper.SaveXmlFileToDialog(SettingsModel.XmlFilePathFolder); if(filePath == null) @@ -100,39 +136,42 @@ namespace VECTO3GUI.ViewModel.Impl SetCurrentDataToSave(); var xDocument = _xmlCompletedBus.GenerateCompletedBusDocument(CompleteVehicleBusData); - if (XmlHelper.ValidateXDocument(xDocument)) { + if (XmlHelper.ValidateXDocument(xDocument, null, ValidationErrorAction)) { _xmlCompletedBusWriter.WriteCompletedBusXml(filePath, xDocument); CloseWindow(window); } } - public ICommand SaveComponent + public ICommand CommitComponent { - get { return _saveComponentCommand ?? - (_saveComponentCommand = new RelayCommand<Component>(DoSaveComponent, CanSaveComponent)); } + get + { + return _commitComponentCommand ?? + (_commitComponentCommand = new RelayCommand<Component>(DoCommitComponent, CanCommitComponent)); + } } - private bool CanSaveComponent(Component component) + private bool CanCommitComponent(Component component) { return ComponentsChanged(component); } - private void DoSaveComponent(Component component) + private void DoCommitComponent(Component component) { - switch (component) { + switch (component) + { case Component.CompleteBusVehicle: - _subModels[Component.CompleteBusVehicle].SaveComponentData(); + _subModels[Component.CompleteBusVehicle].CommitComponentData(); break; case Component.Airdrag: - _subModels[Component.Airdrag].SaveComponentData(); + _subModels[Component.Airdrag].CommitComponentData(); break; case Component.Auxiliaries: - _subModels[Component.Auxiliaries].SaveComponentData(); + _subModels[Component.Auxiliaries].CommitComponentData(); break; } } - public ICommand ResetComponent { get { return _resetComponentCommand ?? @@ -162,9 +201,9 @@ namespace VECTO3GUI.ViewModel.Impl private void SetCurrentDataToSave() { CompleteVehicleBusData = new Dictionary<Component, object> { - { Component.CompleteBusVehicle, _subModels[Component.CompleteBusVehicle].SaveComponentData()}, - { Component.Airdrag, _subModels[Component.Airdrag].SaveComponentData()}, - { Component.Auxiliaries, _subModels[Component.Auxiliaries].SaveComponentData()} + { Component.CompleteBusVehicle, _subModels[Component.CompleteBusVehicle].CommitComponentData()}, + { Component.Airdrag, _subModels[Component.Airdrag].CommitComponentData()}, + { Component.Auxiliaries, _subModels[Component.Auxiliaries].CommitComponentData()} }; } @@ -188,8 +227,59 @@ namespace VECTO3GUI.ViewModel.Impl window?.Close(); } + public ICommand ValidateInput + { + get { return _validateInputCommand ?? (_validateInputCommand = new RelayCommand(DoValidateInput)); } + } + + private void DoValidateInput() + { + _errors = new Dictionary<string, string>(); + + SetCurrentDataToSave(); + var xDoc = _xmlCompletedBus.GenerateCompletedBusDocument(CompleteVehicleBusData); + + if (XmlHelper.ValidateXDocument(xDoc, null, ValidationErrorAction)) + { + _xmlCompletedBusWriter.WriteCompletedBusXml(XmlFilePath, xDoc); + } + } + + public ICommand ValidationErrors + { + get + { + return _validationErrorsCommand ?? (_validationErrorsCommand = new RelayCommand(DoValidationErrors)); + } + } + + private void DoValidationErrors() + { + var completedBusViewModel = _subModels[Component.CompleteBusVehicle] as CompleteVehicleBusViewModel; + var auxiliaryViewModel = _subModels[Component.Auxiliaries] as AuxiliariesViewModel; + + completedBusViewModel?.ShowValidationError(_errors); + auxiliaryViewModel?.ShowValidationError(_errors); + } + + private void ValidationErrorAction(XmlSeverityType arg1, ValidationEvent arg2) + { + var xmlException = arg2?.ValidationEventArgs?.Exception as XmlSchemaValidationException; + if (xmlException != null) + { + var message = xmlException.InnerException; + var sourceObject = xmlException.SourceObject as XmlElement; + var localName = sourceObject?.LocalName; + + if (sourceObject != null) + _errors.Add(localName, message?.Message); + } + } + public string JobFile { get; } public IInputDataProvider InputDataProvider { get; set; } + + } } diff --git a/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusViewModel.cs b/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusViewModel.cs index f6fa37164c..96d4602afd 100644 --- a/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/CompleteVehicleBusViewModel.cs @@ -1,15 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection.Emit; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; +using Castle.Core.Internal; using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider; using VECTO3GUI.Model.TempDataObject; using VECTO3GUI.Util; using VECTO3GUI.ViewModel.Interfaces; @@ -243,6 +239,8 @@ namespace VECTO3GUI.ViewModel.Impl } } + public Dictionary<string, string> XmlNamesToPropertyMapping { get; private set; } + public AllowedEntry<LegislativeClass>[] AllowedLegislativeClasses { get; private set; } public AllowedEntry<VehicleCode>[] AllowedVehicleCodes { get; private set; } public AllowedEntry<ConsumerTechnology>[] AllowedDoorDriveTechnologies { get; private set; } @@ -260,6 +258,8 @@ namespace VECTO3GUI.ViewModel.Impl _vehicle = inputData?.JobInputData.Vehicle; SetVehicleValues(_vehicle); SetAllowedEntries(); + XmlNamesToPropertyMapping = _componentData.XmlNamesToPropertyMapping; + } private void SetVehicleValues(IVehicleDeclarationInputData vehicle) @@ -320,12 +320,26 @@ namespace VECTO3GUI.ViewModel.Impl _componentData.ResetToComponentValues(this); } - public override object SaveComponentData() + public override object CommitComponentData() { _componentData.UpdateCurrentValues(this); ClearChangedProperties(); return _componentData; } + + public override void ShowValidationError(Dictionary<string, string> errors) + { + if (errors.IsNullOrEmpty()) + return; + + foreach (var error in errors) { + + string propertyName; + if (XmlNamesToPropertyMapping.TryGetValue(error.Key, out propertyName)) { + AddPropertyError(propertyName, error.Value); + } + } + } } } diff --git a/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs index b55d315508..ab77ed1075 100644 --- a/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/DeclarationJobViewModel.cs @@ -70,7 +70,7 @@ namespace VECTO3GUI.ViewModel.Impl throw new NotImplementedException(); } - protected override void DoSaveToJob(Window window) + protected override void DoSaveAsJob(Window window) { throw new NotImplementedException(); } @@ -90,6 +90,7 @@ namespace VECTO3GUI.ViewModel.Impl } } - + public ICommand ValidateInput { get; } + public ICommand ValidationErrors { get; } } } diff --git a/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs index 1fd5a9f413..7e25fbb903 100644 --- a/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/EngineOnlyJobViewModel.cs @@ -45,7 +45,10 @@ namespace VECTO3GUI.ViewModel.Impl ); } } - + + public ICommand ValidateInput { get; } + public ICommand ValidationErrors { get; } + #endregion #region Overrides of AbstractJobViewModel @@ -60,7 +63,7 @@ namespace VECTO3GUI.ViewModel.Impl throw new System.NotImplementedException(); } - protected override void DoSaveToJob(Window window) + protected override void DoSaveAsJob(Window window) { throw new System.NotImplementedException(); } diff --git a/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs b/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs index 0d17a35448..8ae295352d 100644 --- a/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/PrimaryVehicleBusJobViewModel.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; +using System.Windows.Input; using Ninject; using TUGraz.VectoCommon.InputData; using VECTO3GUI.Util; @@ -35,7 +36,7 @@ namespace VECTO3GUI.ViewModel.Impl throw new NotImplementedException(); } - protected override void DoSaveToJob(Window window) + protected override void DoSaveAsJob(Window window) { throw new NotImplementedException(); } @@ -45,5 +46,7 @@ namespace VECTO3GUI.ViewModel.Impl get { return string.Empty; } } public IInputDataProvider InputDataProvider { get; set; } + public ICommand ValidateInput { get; } + public ICommand ValidationErrors { get; } } } diff --git a/VECTO3GUI/ViewModel/Impl/ValidatingViewModel.cs b/VECTO3GUI/ViewModel/Impl/ValidatingViewModel.cs index 6e5b8de16f..dae141a735 100644 --- a/VECTO3GUI/ViewModel/Impl/ValidatingViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/ValidatingViewModel.cs @@ -8,167 +8,168 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; +using VECTO3GUI.Helper; using VECTO3GUI.Util; namespace VECTO3GUI.ViewModel.Impl { - public class ValidatingViewModel : ObservableObject, INotifyDataErrorInfo + public class ValidatingViewModel : ViewModelBase // : ObservableObject, INotifyDataErrorInfo { - private readonly Dictionary<string, List<string>> _errors = new Dictionary<string, List<string>>(); - - private readonly Dictionary<string, ValidationAttribute[]> _validations = new Dictionary<string, ValidationAttribute[]>(); - - public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; - - private readonly object _lock = new object(); - - protected ValidatingViewModel() - { - const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public; - var properties = GetType().GetProperties(flags); - - //var classValidation = GetType().GetCustomAttributes<ValidationAttribute>().ToList(); - - foreach (var p in properties) { - if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(ObservableCollection<>)) { - - // var eventInfo = p.PropertyType.GetEvent("CollectionChanged"); - // var methodInfo = GetType().GetMethod("ValidateHandler"); - // var handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, - // methodInfo); - - // eventInfo.AddEventHandler(this, handler); - } - - var attributes = p.GetCustomAttributes<VectoParameterAttribute>().ToList(); - var validationAttributes = p.GetCustomAttributes<ValidationAttribute>().ToList(); - if (attributes.Any() || validationAttributes.Any()) { - var validations = new List<ValidationAttribute>(); - validations.AddRange(GetVectoParameterValidation(attributes)); - validations.AddRange(validationAttributes); - //validations.AddRange(classValidation); - _validations[p.Name] = validations.ToArray(); - } - } - } - - protected void ValidateHandler(object sender, NotifyCollectionChangedEventArgs e) - { - //ValidateProperty(sender); - } - - private ValidationAttribute[] GetVectoParameterValidation(List<VectoParameterAttribute> attributes) - { - if (attributes.Count == 0) { - return new ValidationAttribute[0]; - } - if (attributes.Count != 1) { - throw new Exception(string.Format("Exactly one VectoParameter Attribute allowed! found {0}", attributes.Count)); - } - - var a = attributes.First(); - var p = a.Type.GetProperties().Where(x => x.Name == a.PropertyName).ToArray(); - if (p.Length != 1) { - throw new Exception(string.Format("number of properties found: {0}, expected only 1! {1}:{2}", p.Length, a.Type, a.PropertyName)); - } - - return p.First().GetCustomAttributes<ValidationAttribute>().ToArray(); - } - - - public bool HasErrors - { - get { - lock (_lock) { - return _errors.Any(propErrors => propErrors.Value != null && propErrors.Value.Count > 0); - } - } - } - - public bool IsValid - { - get { return HasErrors; } - } - - public IEnumerable GetErrors(string propertyName) - { - if (string.IsNullOrEmpty(propertyName)) { - lock (_lock) { - return _errors.SelectMany(err => err.Value.ToList()); - } - } - - lock (_lock) { - if (_errors.ContainsKey(propertyName) && _errors[propertyName] != null && _errors[propertyName].Count > 0) { - return _errors[propertyName].ToList(); - } - } - - return null; - } - - private void OnErrorsChanged(string propertyName) - { - if (ErrorsChanged != null) { - ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); - } - } - - protected override bool SetProperty<T>(ref T field, T value, [CallerMemberName] string proptertyName = null) - { - ValidateProperty(value, proptertyName); - return base.SetProperty(ref field, value,proptertyName); - } - - protected void ValidateProperty(object value, [CallerMemberName] string propertyName = null) - { - if (propertyName == null || !_validations.ContainsKey(propertyName)) { - return; - } - lock (_lock) { - var validationContext = new ValidationContext(this) { - MemberName = propertyName, - DisplayName = propertyName, - }; - var validationResults = new List<ValidationResult>(); - Validator.TryValidateValue(value, validationContext, validationResults, _validations[propertyName]); - - if (_errors.ContainsKey(propertyName)) { - _errors.Remove(propertyName); - } - OnErrorsChanged(propertyName); - HandleValidationResults(validationResults); - } - } - - public void Validate() - { - lock (_lock) { - var validationContext = new ValidationContext(this, null, null); - var validationResults = new List<ValidationResult>(); - Validator.TryValidateObject(this, validationContext, validationResults, true); - - //clear all previous _errors - var propNames = _errors.Keys.ToList(); - _errors.Clear(); - propNames.ForEach(OnErrorsChanged); - HandleValidationResults(validationResults); - } - } - - private void HandleValidationResults(List<ValidationResult> validationResults) - { - var resultsByPropNames = from result in validationResults - from member in result.MemberNames - group result by member - into g - select g; - - foreach (var prop in resultsByPropNames) { - var messages = prop.Select(r => r.ErrorMessage).ToList(); - _errors.Add(prop.Key, messages); - OnErrorsChanged(prop.Key); - } - } + //private readonly Dictionary<string, List<string>> _errors = new Dictionary<string, List<string>>(); + + //private readonly Dictionary<string, ValidationAttribute[]> _validations = new Dictionary<string, ValidationAttribute[]>(); + + //public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; + + //private readonly object _lock = new object(); + + //protected ValidatingViewModel() + //{ + // const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public; + // var properties = GetType().GetProperties(flags); + + // //var classValidation = GetType().GetCustomAttributes<ValidationAttribute>().ToList(); + + // foreach (var p in properties) { + // if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(ObservableCollection<>)) { + + // // var eventInfo = p.PropertyType.GetEvent("CollectionChanged"); + // // var methodInfo = GetType().GetMethod("ValidateHandler"); + // // var handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, + // // methodInfo); + + // // eventInfo.AddEventHandler(this, handler); + // } + + // var attributes = p.GetCustomAttributes<VectoParameterAttribute>().ToList(); + // var validationAttributes = p.GetCustomAttributes<ValidationAttribute>().ToList(); + // if (attributes.Any() || validationAttributes.Any()) { + // var validations = new List<ValidationAttribute>(); + // validations.AddRange(GetVectoParameterValidation(attributes)); + // validations.AddRange(validationAttributes); + // //validations.AddRange(classValidation); + // _validations[p.Name] = validations.ToArray(); + // } + // } + //} + + //protected void ValidateHandler(object sender, NotifyCollectionChangedEventArgs e) + //{ + // //ValidateProperty(sender); + //} + + //private ValidationAttribute[] GetVectoParameterValidation(List<VectoParameterAttribute> attributes) + //{ + // if (attributes.Count == 0) { + // return new ValidationAttribute[0]; + // } + // if (attributes.Count != 1) { + // throw new Exception(string.Format("Exactly one VectoParameter Attribute allowed! found {0}", attributes.Count)); + // } + + // var a = attributes.First(); + // var p = a.Type.GetProperties().Where(x => x.Name == a.PropertyName).ToArray(); + // if (p.Length != 1) { + // throw new Exception(string.Format("number of properties found: {0}, expected only 1! {1}:{2}", p.Length, a.Type, a.PropertyName)); + // } + + // return p.First().GetCustomAttributes<ValidationAttribute>().ToArray(); + //} + + + //public bool HasErrors + //{ + // get { + // lock (_lock) { + // return _errors.Any(propErrors => propErrors.Value != null && propErrors.Value.Count > 0); + // } + // } + //} + + //public bool IsValid + //{ + // get { return HasErrors; } + //} + + //public IEnumerable GetErrors(string propertyName) + //{ + // if (string.IsNullOrEmpty(propertyName)) { + // lock (_lock) { + // return _errors.SelectMany(err => err.Value.ToList()); + // } + // } + + // lock (_lock) { + // if (_errors.ContainsKey(propertyName) && _errors[propertyName] != null && _errors[propertyName].Count > 0) { + // return _errors[propertyName].ToList(); + // } + // } + + // return null; + //} + + //private void OnErrorsChanged(string propertyName) + //{ + // if (ErrorsChanged != null) { + // ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); + // } + //} + + //protected override bool SetProperty<T>(ref T field, T value, [CallerMemberName] string proptertyName = null) + //{ + // ValidateProperty(value, proptertyName); + // return base.SetProperty(ref field, value,proptertyName); + //} + + //protected void ValidateProperty(object value, [CallerMemberName] string propertyName = null) + //{ + // if (propertyName == null || !_validations.ContainsKey(propertyName)) { + // return; + // } + // lock (_lock) { + // var validationContext = new ValidationContext(this) { + // MemberName = propertyName, + // DisplayName = propertyName, + // }; + // var validationResults = new List<ValidationResult>(); + // Validator.TryValidateValue(value, validationContext, validationResults, _validations[propertyName]); + + // if (_errors.ContainsKey(propertyName)) { + // _errors.Remove(propertyName); + // } + // OnErrorsChanged(propertyName); + // HandleValidationResults(validationResults); + // } + //} + + //public void Validate() + //{ + // lock (_lock) { + // var validationContext = new ValidationContext(this, null, null); + // var validationResults = new List<ValidationResult>(); + // Validator.TryValidateObject(this, validationContext, validationResults, true); + + // //clear all previous _errors + // var propNames = _errors.Keys.ToList(); + // _errors.Clear(); + // propNames.ForEach(OnErrorsChanged); + // HandleValidationResults(validationResults); + // } + //} + + //private void HandleValidationResults(List<ValidationResult> validationResults) + //{ + // var resultsByPropNames = from result in validationResults + // from member in result.MemberNames + // group result by member + // into g + // select g; + + // foreach (var prop in resultsByPropNames) { + // var messages = prop.Select(r => r.ErrorMessage).ToList(); + // _errors.Add(prop.Key, messages); + // OnErrorsChanged(prop.Key); + // } + //} } } diff --git a/VECTO3GUI/ViewModel/Impl/VehicleViewModel.cs b/VECTO3GUI/ViewModel/Impl/VehicleViewModel.cs index 34a4e0ae05..9e2b1ff3a1 100644 --- a/VECTO3GUI/ViewModel/Impl/VehicleViewModel.cs +++ b/VECTO3GUI/ViewModel/Impl/VehicleViewModel.cs @@ -16,7 +16,6 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Utils; using VECTO3GUI.Util; using VECTO3GUI.ViewModel.Adapter; -using VECTO3GUI.ViewModel.Adapter.Declaration; using VECTO3GUI.ViewModel.Interfaces; using Component = VECTO3GUI.Util.Component; @@ -172,7 +171,7 @@ namespace VECTO3GUI.ViewModel.Impl { get { return _manufacturer; } set { - ValidateProperty(value); + //ValidateProperty(value); SetProperty(ref _manufacturer, value); } } diff --git a/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs b/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs index 1846bd45e1..29adc34c85 100644 --- a/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs +++ b/VECTO3GUI/ViewModel/Interfaces/IAuxiliariesBus.cs @@ -37,6 +37,6 @@ namespace VECTO3GUI.ViewModel.Interfaces #endregion - + Dictionary<string, string> XmlNamesToPropertyMapping { get; } } } diff --git a/VECTO3GUI/ViewModel/Interfaces/ICompleteVehicleBus.cs b/VECTO3GUI/ViewModel/Interfaces/ICompleteVehicleBus.cs index d50ebcc190..ed824496a4 100644 --- a/VECTO3GUI/ViewModel/Interfaces/ICompleteVehicleBus.cs +++ b/VECTO3GUI/ViewModel/Interfaces/ICompleteVehicleBus.cs @@ -36,5 +36,7 @@ namespace VECTO3GUI.ViewModel.Interfaces ConsumerTechnology DoorDriveTechnology { get; set; } #endregion + + Dictionary<string,string> XmlNamesToPropertyMapping { get; } } } diff --git a/VECTO3GUI/ViewModel/Interfaces/IComponentViewModel.cs b/VECTO3GUI/ViewModel/Interfaces/IComponentViewModel.cs index 6dfd1cb5cb..1db0e7cdfe 100644 --- a/VECTO3GUI/ViewModel/Interfaces/IComponentViewModel.cs +++ b/VECTO3GUI/ViewModel/Interfaces/IComponentViewModel.cs @@ -1,8 +1,7 @@ +using System.Collections.Generic; using System.Collections.ObjectModel; -using TUGraz.VectoCommon.InputData; -using VECTO3GUI.Model.TempDataObject; using VECTO3GUI.Util; -using VECTO3GUI.ViewModel.Impl; + namespace VECTO3GUI.ViewModel.Interfaces { public interface IComponentViewModel @@ -20,7 +19,9 @@ namespace VECTO3GUI.ViewModel.Interfaces { bool IsComponentDataChanged(); void ResetComponentData(); - object SaveComponentData(); + object CommitComponentData(); + + void ShowValidationError(Dictionary<string, string> errors); } diff --git a/VECTO3GUI/ViewModel/Interfaces/IJobEditViewModel.cs b/VECTO3GUI/ViewModel/Interfaces/IJobEditViewModel.cs index 062c08f389..2d7a7c67a8 100644 --- a/VECTO3GUI/ViewModel/Interfaces/IJobEditViewModel.cs +++ b/VECTO3GUI/ViewModel/Interfaces/IJobEditViewModel.cs @@ -18,8 +18,10 @@ namespace VECTO3GUI.ViewModel.Interfaces IComponentViewModel CurrentComponent { get; } ICommand SaveJob { get; } - ICommand SaveToJob { get; } + ICommand SaveAsJob { get; } ICommand CloseJob { get; } + ICommand ValidateInput { get; } + ICommand ValidationErrors { get; } } } diff --git a/VECTO3GUI/Views/ComponentViews/Declaration/AuxiliariesDeclarationView.xaml b/VECTO3GUI/Views/ComponentViews/Declaration/AuxiliariesDeclarationView.xaml index fe20e10698..4f27683225 100644 --- a/VECTO3GUI/Views/ComponentViews/Declaration/AuxiliariesDeclarationView.xaml +++ b/VECTO3GUI/Views/ComponentViews/Declaration/AuxiliariesDeclarationView.xaml @@ -48,7 +48,7 @@ Command="{Binding RemoveAllAlternatorCommand}"/> </Grid> - + <DataGrid x:Name="AlternatorDataGrid" AutoGenerateColumns="False" ColumnWidth="*" IsReadOnly="False" CanUserAddRows="False" VerticalAlignment="Top" HeadersVisibility="All" RowHeaderWidth="10" Height="120" Margin="0,10,0,0" BorderThickness="1" ItemsSource="{Binding AlternatorTechnologies}"> @@ -81,12 +81,12 @@ </DataGrid.Columns> </DataGrid> - + </StackPanel> </GroupBox> <GroupBox Header="Electric Systems" Grid.Row="2" Grid.Column="1" Margin="0,10,0,0" Width="450" HorizontalAlignment="Left"> - + <StackPanel Orientation="Vertical" Width="400" HorizontalAlignment="Left" Grid.IsSharedSizeScope="True" VerticalAlignment="Center" > <customControls:CheckboxParameter @@ -120,49 +120,114 @@ <GroupBox Header="HVAC" Grid.Row="3" Grid.Column="1" Margin="0,10,0,0" Width="450" HorizontalAlignment="Left"> <StackPanel Orientation="Vertical" Width="400" HorizontalAlignment="Left" Grid.IsSharedSizeScope="True" VerticalAlignment="Center" > - <customControls:ComboParameter + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="lblWidth"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="System Configuration" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedSystemConfigurations}" + SelectedValue="{Binding SystemConfiguration, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="System Configuration" CaptionWidthGroup="lblWidth" UnitWidthGroup="unitWidth" Value="{Binding SystemConfiguration}" - AllowedValues="{Binding AllowedSystemConfigurations}" /> + AllowedValues="{Binding AllowedSystemConfigurations}" />--> - <customControls:ComboParameter + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="lblWidth"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="Compressor Type Driver" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedDriverACCompressorTypes}" + SelectedValue="{Binding CompressorTypeDriver, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="Compressor Type Driver" CaptionWidthGroup="lblWidth" UnitWidthGroup="unitWidth" Value="{Binding CompressorTypeDriver}" - AllowedValues="{Binding AllowedDriverACCompressorTypes}" /> + AllowedValues="{Binding AllowedDriverACCompressorTypes}" />--> - <customControls:ComboParameter + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="lblWidth"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="Compressor Type Passenger" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedPassengerACCompressorTypes}" + SelectedValue="{Binding CompressorTypePassenger, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="Compressor Type Passenger" CaptionWidthGroup="lblWidth" UnitWidthGroup="unitWidth" Value="{Binding CompressorTypePassenger}" - AllowedValues="{Binding AllowedPassengerACCompressorTypes}" /> + AllowedValues="{Binding AllowedPassengerACCompressorTypes}" />--> + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="lblWidth"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Aux Heater Power" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding AuxHeaterPower, Converter={converter:SIValueConverter}, ConverterParameter=double, + Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> - <customControls:VectoParameterControl + <TextBlock Grid.Row="0" Grid.Column="2" Text="{helper:SIUnit AuxHeaterPower}" Margin="5,0,5,0"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Aux Heater Power" Unit="{helper:SIUnit AuxHeaterPower}" CaptionWidthGroup="lblWidth" UnitWidthGroup="unitWidth" - Value="{Binding AuxHeaterPower, Converter={converter:SIValueConverter}, ConverterParameter=double}" /> + Value="{Binding AuxHeaterPower, Converter={converter:SIValueConverter}, ConverterParameter=double}" />--> - <customControls:CheckboxParameter + <customControls:CheckboxParameter Caption="Double Glasing" CaptionWidthGroup="lblWidth" Unit="" UnitWidthGroup="unitWidth" Value="{Binding DoubleGlasing}"/> - <customControls:CheckboxParameter + <customControls:CheckboxParameter Caption="Heat Pump" CaptionWidthGroup="lblWidth" Unit="" UnitWidthGroup="unitWidth" Value="{Binding HeatPump}"/> - <customControls:CheckboxParameter + <customControls:CheckboxParameter Caption="Adjustable Auxiliary Heater" CaptionWidthGroup="lblWidth" Unit="" UnitWidthGroup="unitWidth" Value="{Binding AdjustableAuxiliaryHeater}"/> - <customControls:CheckboxParameter + <customControls:CheckboxParameter Caption="Separate Air Distribution Ducts" CaptionWidthGroup="lblWidth" Unit="" UnitWidthGroup="unitWidth" Value="{Binding SeparateAirDistributionDucts}"/> - </StackPanel> - </GroupBox> + </StackPanel> + </GroupBox> </Grid> </UserControl> diff --git a/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml b/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml index 8a4f39dd81..afd1915fc9 100644 --- a/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml +++ b/VECTO3GUI/Views/ComponentViews/Declaration/CompleteVehicleBusView.xaml @@ -32,66 +32,222 @@ <StackPanel Orientation="Vertical" Width="400" HorizontalAlignment="Left" Grid.IsSharedSizeScope="True" VerticalAlignment="Center"> <StackPanel Orientation="Vertical" DockPanel.Dock="Top" Grid.IsSharedSizeScope="True"> - <customControls:VectoParameterControl + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + + <TextBlock Grid.Column="0" Text="Manufacturer" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding Manufacturer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Manufacturer" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding Manufacturer}" > - </customControls:VectoParameterControl> + Value="{Binding Manufacturer}" />--> - <customControls:VectoParameterControl + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Manufacturer Address" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding ManufacturerAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Manufacturer Address" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding ManufacturerAddress}" /> - <customControls:VectoParameterControl - Caption="VIN" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding VIN}" /> + Value="{Binding ManufacturerAddress}" />--> + + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Model" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding Model, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + </Grid> + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="VIN" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding VIN, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + </Grid> <!--<customControls:VectoParameterControl - Caption="Date" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding Date}" />--> + Caption="VIN" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" + Value="{Binding VIN}" />--> - <customControls:ComboParameter + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="Legislative Class" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedLegislativeClasses}" + SelectedValue="{Binding LegislativeClass, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="Legislative Class" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" Value="{Binding LegislativeClass}" - AllowedValues="{Binding AllowedLegislativeClasses}" /> + AllowedValues="{Binding AllowedLegislativeClasses}" />--> - <!--<customControls:VectoParameterControl - Caption="Registered Class" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding RegisteredClass}"/>--> - <customControls:ComboParameter + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="Registered Class" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedRegisteredClasses}" + SelectedValue="{Binding RegisteredClass, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="Registered Class" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" Value="{Binding RegisteredClass}" - AllowedValues="{Binding AllowedRegisteredClasses}" /> + AllowedValues="{Binding AllowedRegisteredClasses}" />--> - <customControls:ComboParameter + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="Vehicle Code" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedVehicleCodes}" + SelectedValue="{Binding VehicleCode, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="Vehicle Code" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" Value="{Binding VehicleCode}" - AllowedValues="{Binding AllowedVehicleCodes}" /> + AllowedValues="{Binding AllowedVehicleCodes}" />--> - <customControls:VectoParameterControl + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Curb Mass Chassis" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding CurbMassChassis, Converter={converter:SIValueConverter}, ConverterParameter=int, + Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + <TextBlock Grid.Row="0" Grid.Column="2" Text="{helper:SIUnit CurbMassChassis}" Margin="5,0,5,0"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Curb Mass Chassis" Unit="{helper:SIUnit CurbMassChassis}" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding CurbMassChassis, Converter={converter:SIValueConverter}, ConverterParameter=int}" /> + Value="{Binding CurbMassChassis, Converter={converter:SIValueConverter}, ConverterParameter=int}" />--> + - <customControls:VectoParameterControl + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Permissible Maximum Laden Mass" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding TechnicalPermissibleMaximumLadenMass, Converter={converter:SIValueConverter}, ConverterParameter=int, + Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + <TextBlock Grid.Row="0" Grid.Column="2" Text="{helper:SIUnit TechnicalPermissibleMaximumLadenMass}" Margin="5,0,5,0"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Permissible Maximum Laden Mass" Unit="{helper:SIUnit TechnicalPermissibleMaximumLadenMass}" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding TechnicalPermissibleMaximumLadenMass, Converter={converter:SIValueConverter}, ConverterParameter=int}" /> + Value="{Binding TechnicalPermissibleMaximumLadenMass, Converter={converter:SIValueConverter}, ConverterParameter=int}" />--> + - <customControls:ComboParameter + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="Tank System" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedTankSystems}" + SelectedValue="{Binding NgTankSystem, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="Tank System" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" Value="{Binding NgTankSystem}" - AllowedValues="{Binding AllowedTankSystems}" /> + AllowedValues="{Binding AllowedTankSystems}" />--> - <customControls:VectoParameterControl + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Passengers Lower Deck" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding NumberOfPassengersLowerDeck, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Passengers Lower Deck" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding NumberOfPassengersLowerDeck}" /> + Value="{Binding NumberOfPassengersLowerDeck}" />--> - <customControls:VectoParameterControl + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Passengers Upper Deck" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding NumberOfPassengersUpperDeck, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Passengers Upper Deck" Unit="" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding NumberOfPassengersUpperDeck}" /> + Value="{Binding NumberOfPassengersUpperDeck}" />--> <customControls:CheckboxParameter Caption="Low Entry" CaptionWidthGroup="vehicleLbl" @@ -99,28 +255,97 @@ Value="{Binding LowEntry}"/> - <customControls:VectoParameterControl + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Height Integrated Body" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding HeightIntegratedBody, Converter={converter:SIValueConverter}, ConverterParameter=double, + Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + + <TextBlock Grid.Row="0" Grid.Column="2" Text="{helper:SIUnit HeightIntegratedBody}" Margin="5,0,5,0"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Height Integrated Body" Unit="{helper:SIUnit HeightIntegratedBody}" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding HeightIntegratedBody, Converter={converter:SIValueConverter}, ConverterParameter=double}" /> + Value="{Binding HeightIntegratedBody, Converter={converter:SIValueConverter}, ConverterParameter=double}" />--> + - <customControls:VectoParameterControl + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Vehicle Length" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding VehicleLength, Converter={converter:SIValueConverter}, ConverterParameter=double, + Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + <TextBlock Grid.Row="0" Grid.Column="2" Text="{helper:SIUnit VehicleLength}" Margin="5,0,5,0"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Vehicle Length" Unit="{helper:SIUnit VehicleLength}" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding VehicleLength, Converter={converter:SIValueConverter}, ConverterParameter=double}" /> + Value="{Binding VehicleLength, Converter={converter:SIValueConverter}, ConverterParameter=double}" />--> + - <customControls:VectoParameterControl + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Vehicle Width" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding VehicleWidth, Converter={converter:SIValueConverter}, ConverterParameter=double, + Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + <TextBlock Grid.Row="0" Grid.Column="2" Text="{helper:SIUnit VehicleWidth}" Margin="5,0,5,0"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Vehicle Width" Unit="{helper:SIUnit VehicleWidth}" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding VehicleWidth, Converter={converter:SIValueConverter}, ConverterParameter=double}" /> + Value="{Binding VehicleWidth, Converter={converter:SIValueConverter}, ConverterParameter=double}" />--> + - <customControls:VectoParameterControl + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Column="0" Text="Entrance Height" Margin="0,0,10,0"/> + <TextBox Grid.Column="1" Margin="20,0,0,0" + Text="{Binding EntranceHeight, Converter={converter:SIValueConverter}, ConverterParameter=double, + Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/> + <TextBlock Grid.Row="0" Grid.Column="2" Text="{helper:SIUnit EntranceHeight}" Margin="5,0,5,0"/> + </Grid> + <!--<customControls:VectoParameterControl Caption="Entrance Height" Unit="{helper:SIUnit EntranceHeight}" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" - Value="{Binding EntranceHeight, Converter={converter:SIValueConverter}, ConverterParameter=double}" /> + Value="{Binding EntranceHeight, Converter={converter:SIValueConverter}, ConverterParameter=double}" />--> - <customControls:ComboParameter + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition SharedSizeGroup="vehicleLbl"/> + <ColumnDefinition /> + <ColumnDefinition SharedSizeGroup="unitWidth"/> + </Grid.ColumnDefinitions> + <TextBlock Grid.Row="0" Grid.Column="0" Text="Door Drive Technology" Margin="0,0,10,0"/> + <ComboBox Grid.Column="1" + Margin="20,0,0,0" + ItemsSource="{Binding AllowedDoorDriveTechnologies}" + SelectedValue="{Binding DoorDriveTechnology, Mode=TwoWay ,ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" + SelectedValuePath="Value" + DisplayMemberPath="Label" + IsEditable="True" + IsReadOnly="True" + Text="Select..."/> + </Grid> + <!--<customControls:ComboParameter Caption="Door Drive Technology" CaptionWidthGroup="vehicleLbl" UnitWidthGroup="unitWidth" Value="{Binding DoorDriveTechnology}" - AllowedValues="{Binding AllowedDoorDriveTechnologies}" /> + AllowedValues="{Binding AllowedDoorDriveTechnologies}" />--> </StackPanel> </StackPanel> diff --git a/VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml b/VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml new file mode 100644 index 0000000000..2271557a90 --- /dev/null +++ b/VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml @@ -0,0 +1,46 @@ +<UserControl x:Class="VECTO3GUI.Views.CustomControls.IntegerVectoParameterControl" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:VECTO3GUI.Views.CustomControls" + xmlns:validation="clr-namespace:VECTO3GUI.Helper.Validation" + mc:Ignorable="d" + d:DesignHeight="40" d:DesignWidth="300" d:DataContext="{d:DesignInstance {x:Type local:IntegerVectoParameterControl}}"> + + <Grid Margin="5"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" SharedSizeGroup="{Binding CaptionWidthGroup}"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="Auto" SharedSizeGroup="{Binding UnitWidthGroup}"/> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> + + <TextBlock Grid.Row="0" Grid.Column="0" Margin="0,0,10,0" Text="{Binding Caption}" /> + <TextBox Grid.Row="0" Grid.Column="1" Margin="20,0,0,0" TextAlignment="{Binding ValueAlign}" x:Name="txtName" > + <TextBox.Resources> + <validation:IntegerValidatorConfig x:Key="IntValidator" MinValue="{Binding MinValue}" MaxValue="{Binding MaxValue}" ValidateInput="{Binding ValidateInput}"/> + </TextBox.Resources> + <!--http://geekswithblogs.net/NewThingsILearned/archive/2008/01/15/binding-to-an-attached-property.aspx--> + <TextBox.Text > + <Binding Delay="100" + Mode="TwoWay" + NotifyOnSourceUpdated="True" + NotifyOnTargetUpdated="True" + NotifyOnValidationError="True" + Path="Value" + UpdateSourceTrigger="PropertyChanged" + ValidatesOnDataErrors="True" + ValidatesOnExceptions="True"> + <Binding.ValidationRules> + <validation:IntegerValidator ValidatorConfig="{StaticResource IntValidator}" /> + </Binding.ValidationRules> + </Binding> + </TextBox.Text> + </TextBox> + + <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Unit}" Margin="5,0,5,0"/> + </Grid> +</UserControl> diff --git a/VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml.cs b/VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml.cs new file mode 100644 index 0000000000..da8a649475 --- /dev/null +++ b/VECTO3GUI/Views/CustomControls/IntegerVectoParameterControl.xaml.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace VECTO3GUI.Views.CustomControls +{ + /// <summary> + /// Interaction logic for OtherVectoParameterControl.xaml + /// </summary> + public partial class IntegerVectoParameterControl : UserControl, IDataErrorInfo + + + //, INotifyDataErrorInfo + { + public IntegerVectoParameterControl() + { + InitializeComponent(); + (Content as FrameworkElement).DataContext = this; + + + + } + + + public string Caption + { + get { return (string)GetValue(CaptionProperty); } + set { SetValue(CaptionProperty, value); } + } + + public static explicit operator IntegerVectoParameterControl(BindingExpression v) + { + throw new NotImplementedException(); + } + + //Using a DependencyProperty as the backing store for Caption.This enables animation, styling, binding, etc... + public static readonly DependencyProperty CaptionProperty = + DependencyProperty.Register(nameof(Caption), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata(string.Empty)); + + + public string Value + { + get { return (string)GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + + //Using a DependencyProperty as the backing store for Value.This enables animation, styling, binding, etc... + public static readonly DependencyProperty ValueProperty = + DependencyProperty.Register(nameof(Value), typeof(string), typeof(IntegerVectoParameterControl), new FrameworkPropertyMetadata() { BindsTwoWayByDefault = true }); + + + public string Unit + { + get { return (string)GetValue(UnitProperty); } + set { SetValue(UnitProperty, value); } + } + + // Using a DependencyProperty as the backing store for Unit. This enables animation, styling, binding, etc... + public static readonly DependencyProperty UnitProperty = + DependencyProperty.Register(nameof(Unit), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata("")); + + + + + public string ValueAlign + { + get { return (string)GetValue(ValueAlignProperty); } + set { SetValue(ValueAlignProperty, value); } + } + + // Using a DependencyProperty as the backing store for ValueAlign. This enables animation, styling, binding, etc... + public static readonly DependencyProperty ValueAlignProperty = + DependencyProperty.Register(nameof(ValueAlign), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata("left")); + + + + public string CaptionWidthGroup + { + get { return (string)GetValue(CaptionWidthGroupProperty); } + set { SetValue(CaptionWidthGroupProperty, value); } + } + + // Using a DependencyProperty as the backing store for CaptionWidthGroup. This enables animation, styling, binding, etc... + public static readonly DependencyProperty CaptionWidthGroupProperty = + DependencyProperty.Register(nameof(CaptionWidthGroup), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata("")); + + + public string UnitWidthGroup + { + get { return (string)GetValue(UnitWidthGroupProperty); } + set { SetValue(UnitWidthGroupProperty, value); } + } + + // Using a DependencyProperty as the backing store for UnitWidthGroup. This enables animation, styling, binding, etc... + public static readonly DependencyProperty UnitWidthGroupProperty = + DependencyProperty.Register(nameof(UnitWidthGroup), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata("")); + + + public string MinValue + { + get { return (string)GetValue(MinValueProperty); } + set { SetValue(MinValueProperty, value);} + } + + public static readonly DependencyProperty MinValueProperty = + DependencyProperty.Register(nameof(MinValue), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata($"{int.MinValue}")); + + + public string MaxValue + { + get { return (string)GetValue(MaxValueProperty); } + set { SetValue(MaxValueProperty, value); } + } + + public static readonly DependencyProperty MaxValueProperty = + DependencyProperty.Register(nameof(MaxValue), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata($"{int.MaxValue}")); + + + public string ValidateInput + { + get { return (string)GetValue(ValidateInputProperty); } + set { SetValue(ValidateInputProperty, value); } + } + + public static readonly DependencyProperty ValidateInputProperty = + DependencyProperty.Register(nameof(ValidateInput), typeof(string), typeof(IntegerVectoParameterControl), new PropertyMetadata("False")); + + + + + + //public IEnumerable GetErrors(string propertyName) + //{ + // var validationErrors = Validation.GetErrors(this); + // var specificValidationErrors = + // validationErrors.Where( + // error => ((BindingExpression)error.BindingInError).TargetProperty.Name == propertyName).ToList(); + // var specificValidationErrorMessages = specificValidationErrors.Select(valError => valError.ErrorContent); + // return specificValidationErrorMessages; + //} + + //public bool HasErrors + //{ + // get + // { + // var validationErrors = Validation.GetErrors(this); + // return validationErrors.Any(); + // } + //} + + //public void NotifyErrorsChanged(string propertyName) + //{ + // if (ErrorsChanged != null) + // { + // ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); + // } + //} + + + //public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; + public string this[string columnName] + { + get { return $"blabla{columnName}"; } + } + + public string Error { get; } + } +} diff --git a/VECTO3GUI/Views/JoblistTabView.xaml b/VECTO3GUI/Views/JoblistTabView.xaml index 54a665f085..08e2463c8a 100644 --- a/VECTO3GUI/Views/JoblistTabView.xaml +++ b/VECTO3GUI/Views/JoblistTabView.xaml @@ -32,12 +32,19 @@ <MenuItem Header="Save" Command="{Binding SaveJob}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> - <MenuItem Header="Save to" Command="{Binding SaveToJob}"/> + <MenuItem Header="Save As..." Command="{Binding SaveAsJob}"/> <Separator HorizontalAlignment="Stretch" Background="Gray"/> <MenuItem Header="Close" Command="{Binding CloseJob}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> </MenuItem> + + <MenuItem Header="Input Validation"> + <MenuItem Header="Validate" + Command="{Binding ValidateInput}"/> + <MenuItem Header="Validation Errors" + Command="{Binding ValidationErrors}"/> + </MenuItem> </Menu> <Separator HorizontalAlignment="Stretch" Background="Gray"/> </StackPanel> @@ -73,8 +80,13 @@ <TabControl.ContentTemplate> <DataTemplate> <ScrollViewer DockPanel.Dock="Top"> - <ContentControl Content="{Binding DataContext.CurrentComponent, - RelativeSource={RelativeSource AncestorType=local:JoblistTabView}}" Margin="0,20,0,10"/> + <AdornerDecorator> + <Grid> + <ContentControl Content="{Binding DataContext.CurrentComponent, + RelativeSource={RelativeSource AncestorType=local:JoblistTabView}}" Margin="0,20,0,10"/> + </Grid> + </AdornerDecorator> + </ScrollViewer> </DataTemplate> </TabControl.ContentTemplate> @@ -89,10 +101,25 @@ <StackPanel Orientation="Vertical" VerticalAlignment="Center"> <Separator HorizontalAlignment="Stretch" Background="Gray"/> <Grid> - <Button Content="{Binding ElementName=ComponentsTab, Path=SelectedItem, Converter={converter:SaveButtonLabelConverter}}" - HorizontalAlignment="Right" Margin="0,0,15,0" - Command="{Binding SaveComponent}" CommandParameter="{Binding ElementName=ComponentsTab, Path=SelectedItem}"/> - <Button Content="Reset" HorizontalAlignment="Left" Margin="15,0,0,0" + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,15,0"> + <Button HorizontalAlignment="Right" MinWidth="80" Margin="0,0,10,0" + Content="Save As..." Visibility="{Binding SaveAsButtonVisible, Converter={converter:BoolVisibilityConverter}}" + Command="{Binding SaveAsJob}" + CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> + + <Button HorizontalAlignment="Right" MinWidth="80" Margin="0,0,10,0" + Content="Save" Visibility="{Binding SaveButtonVisibility, Converter={converter:BoolVisibilityConverter}}" + Command="{Binding SaveJob}" + CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> + + <Button HorizontalAlignment="Right" MinWidth="140" + Content="{Binding ElementName=ComponentsTab, Path=SelectedItem, + Converter={converter:SaveButtonLabelConverter}, ConverterParameter='Commit'}" + Command="{Binding CommitComponent}" CommandParameter="{Binding ElementName=ComponentsTab, Path=SelectedItem}"/> + </StackPanel> + + + <Button Content="Reset" HorizontalAlignment="Left" Margin="15,0,0,0" MinWidth="80" Command="{Binding ResetComponent}" CommandParameter="{Binding ElementName=ComponentsTab, Path=SelectedItem}"/> </Grid> </StackPanel> -- GitLab