diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs index 601483aef..a297c65c2 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs @@ -181,6 +181,24 @@ namespace Artemis.Core return true; } + /// + /// Determines the best type to use for the right side op this predicate + /// + public Type? GetPreferredRightSideType() + { + Type? preferredType = Operator?.RightSideType; + Type? leftSideType = DataModelConditionList.IsPrimitiveList + ? DataModelConditionList.ListType + : LeftPath?.GetPropertyType(); + if (preferredType == null) + return null; + + if (leftSideType != null && preferredType.IsAssignableFrom(leftSideType)) + preferredType = leftSideType; + + return preferredType; + } + #region IDisposable /// @@ -411,13 +429,14 @@ namespace Artemis.Core } // If not null ensure the types match and if not, convert it - if (staticValue != null && staticValue.GetType() == Operator.RightSideType) + Type? preferredType = GetPreferredRightSideType(); + if (staticValue != null && staticValue.GetType() == preferredType || preferredType == null) RightStaticValue = staticValue; else if (staticValue != null) - RightStaticValue = Convert.ChangeType(staticValue, Operator.RightSideType); + RightStaticValue = Convert.ChangeType(staticValue, preferredType); // If null create a default instance for value types or simply make it null for reference types - else if (Operator.RightSideType.IsValueType) - RightStaticValue = Activator.CreateInstance(Operator.RightSideType); + else if (preferredType.IsValueType) + RightStaticValue = Activator.CreateInstance(preferredType); else RightStaticValue = null; } diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionPredicate.cs index db96b8c22..72b693f5d 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionPredicate.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionPredicate.cs @@ -1,6 +1,4 @@ using System; -using System.IO; -using Artemis.Core.DataModelExpansions; using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Conditions; using Newtonsoft.Json; @@ -113,6 +111,7 @@ namespace Artemis.Core RightStaticValue = staticValue; return; } + // If the operator does not support a right side, always set it to null if (Operator.RightSideType == null) { @@ -121,13 +120,14 @@ namespace Artemis.Core } // If not null ensure the types match and if not, convert it - if (staticValue != null && staticValue.GetType() == Operator.RightSideType) + Type? preferredType = GetPreferredRightSideType(); + if (staticValue != null && staticValue.GetType() == preferredType || preferredType == null) RightStaticValue = staticValue; else if (staticValue != null) - RightStaticValue = Convert.ChangeType(staticValue, Operator.RightSideType); + RightStaticValue = Convert.ChangeType(staticValue, preferredType); // If null create a default instance for value types or simply make it null for reference types - else if (Operator.RightSideType.IsValueType) - RightStaticValue = Activator.CreateInstance(Operator.RightSideType); + else if (preferredType.IsValueType) + RightStaticValue = Activator.CreateInstance(preferredType); else RightStaticValue = null; } @@ -184,6 +184,22 @@ namespace Artemis.Core return Operator.InternalEvaluate(LeftPath.GetValue(), RightPath.GetValue()); } + /// + /// Determines the best type to use for the right side op this predicate + /// + public Type? GetPreferredRightSideType() + { + Type? preferredType = Operator?.RightSideType; + Type? leftSideType = LeftPath?.GetPropertyType(); + if (preferredType == null) + return null; + + if (leftSideType != null && preferredType.IsAssignableFrom(leftSideType)) + preferredType = leftSideType; + + return preferredType; + } + /// public override string ToString() { diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs index 343f01028..11c993fc9 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelStaticViewModel.cs @@ -69,7 +69,7 @@ namespace Artemis.UI.Shared.Input public Type TargetType { get => _targetType; - set => SetAndNotify(ref _targetType, value); + private set => SetAndNotify(ref _targetType, value); } public DataModelPropertyAttribute TargetDescription diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs index 658ac8c92..535bdb323 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs @@ -156,14 +156,16 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions { DisposeRightSideDynamicViewModel(); if (RightSideInputViewModel == null) - CreateRightSideInputViewModel(SelectedOperator.RightSideType); + CreateRightSideInputViewModel(); if (SelectedOperator.RightSideType.IsValueType && DataModelConditionListPredicate.RightStaticValue == null) RightSideInputViewModel.Value = SelectedOperator.RightSideType.GetDefault(); else RightSideInputViewModel.Value = DataModelConditionListPredicate.RightStaticValue; - if (RightSideInputViewModel.TargetType != SelectedOperator.RightSideType) - RightSideInputViewModel.UpdateTargetType(SelectedOperator.RightSideType); + + Type preferredType = DataModelConditionListPredicate.GetPreferredRightSideType(); + if (RightSideInputViewModel.TargetType != preferredType) + RightSideInputViewModel.UpdateTargetType(preferredType); } } @@ -222,7 +224,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions SelectedOperator = dataModelConditionOperator; ApplyOperator(); } - + #region IDisposable public void Dispose() @@ -286,9 +288,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions RightSideSelectionViewModel.ExtraDataModelViewModels.Add(listValue); } - private void CreateRightSideInputViewModel(Type leftSideType) + private void CreateRightSideInputViewModel() { - RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(leftSideType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription()); + Type preferredType = DataModelConditionListPredicate.GetPreferredRightSideType(); + RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(preferredType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription()); RightSideInputViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush"); RightSideInputViewModel.DisplaySwitchButton = true; RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs index a67214d63..4f1fa2f08 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionPredicateViewModel.cs @@ -131,14 +131,16 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions { DisposeRightSideDynamicViewModel(); if (RightSideInputViewModel == null) - CreateRightSideInputViewModel(SelectedOperator.RightSideType); + CreateRightSideInputViewModel(); if (SelectedOperator.RightSideType.IsValueType && DataModelConditionPredicate.RightStaticValue == null) RightSideInputViewModel.Value = SelectedOperator.RightSideType.GetDefault(); else RightSideInputViewModel.Value = DataModelConditionPredicate.RightStaticValue; - if (RightSideInputViewModel.TargetType != SelectedOperator.RightSideType) - RightSideInputViewModel.UpdateTargetType(SelectedOperator.RightSideType); + + Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType(); + if (RightSideInputViewModel.TargetType != preferredType) + RightSideInputViewModel.UpdateTargetType(preferredType); } } @@ -188,7 +190,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions SelectedOperator = DataModelConditionOperator; ApplyOperator(); } - + #region IDisposable public void Dispose() @@ -217,9 +219,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions RightSideSelectionViewModel.SwitchToStaticRequested += RightSideSelectionViewModelOnSwitchToStaticRequested; } - private void CreateRightSideInputViewModel(Type leftSideType) + private void CreateRightSideInputViewModel() { - RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(leftSideType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription()); + Type preferredType = DataModelConditionPredicate.GetPreferredRightSideType(); + RightSideInputViewModel = _dataModelUIService.GetStaticInputViewModel(preferredType, LeftSideSelectionViewModel.DataModelPath?.GetPropertyDescription()); RightSideInputViewModel.ButtonBrush = (SolidColorBrush) Application.Current.FindResource("PrimaryHueMidBrush"); RightSideInputViewModel.DisplaySwitchButton = true; RightSideInputViewModel.ValueUpdated += RightSideOnValueEntered;