wip
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Xaml.Interactions.Core;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.UI.WinUI;
|
||||
|
||||
public class ComparisonCondition :
|
||||
DependencyObject,
|
||||
ICondition
|
||||
{
|
||||
public static readonly DependencyProperty LeftOperandProperty =
|
||||
DependencyProperty.Register(nameof(LeftOperand),
|
||||
typeof(object), typeof(ComparisonCondition),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public static readonly DependencyProperty OperatorProperty =
|
||||
DependencyProperty.Register(nameof(Operator),
|
||||
typeof(ComparisonConditionType), typeof(ComparisonCondition),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public static readonly DependencyProperty RightOperandProperty =
|
||||
DependencyProperty.Register(nameof(RightOperand),
|
||||
typeof(object), typeof(ComparisonCondition),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public object LeftOperand
|
||||
{
|
||||
get => GetValue(LeftOperandProperty);
|
||||
set => SetValue(LeftOperandProperty, value);
|
||||
}
|
||||
|
||||
public object RightOperand
|
||||
{
|
||||
get => GetValue(RightOperandProperty);
|
||||
set => SetValue(RightOperandProperty, value);
|
||||
}
|
||||
|
||||
public ComparisonConditionType Operator
|
||||
{
|
||||
get => (ComparisonConditionType)GetValue(OperatorProperty);
|
||||
set => SetValue(OperatorProperty, value);
|
||||
}
|
||||
|
||||
public bool Evaluate() =>
|
||||
ComparisonLogic.Evaluate(LeftOperand, Operator, RightOperand);
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using Microsoft.Xaml.Interactions.Core;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Toolkit.UI.WinUI;
|
||||
|
||||
internal static class ComparisonLogic
|
||||
{
|
||||
internal static bool Evaluate(object leftOperand,
|
||||
ComparisonConditionType operatorType,
|
||||
object? rightOperand)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (leftOperand != null)
|
||||
{
|
||||
Type leftType = leftOperand.GetType();
|
||||
|
||||
if (rightOperand != null)
|
||||
{
|
||||
TypeConverter typeConverter = TypeDescriptor.GetConverter(leftType);
|
||||
rightOperand = typeConverter.ConvertFrom(rightOperand);
|
||||
}
|
||||
}
|
||||
|
||||
if (leftOperand is IComparable leftComparableOperand &&
|
||||
rightOperand is IComparable rightComparableOperand)
|
||||
{
|
||||
return EvaluateComparable(leftComparableOperand, operatorType, rightComparableOperand);
|
||||
}
|
||||
|
||||
switch (operatorType)
|
||||
{
|
||||
case ComparisonConditionType.Equal:
|
||||
result = Equals(leftOperand, rightOperand);
|
||||
break;
|
||||
|
||||
case ComparisonConditionType.NotEqual:
|
||||
result = !Equals(leftOperand, rightOperand);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool EvaluateComparable(IComparable leftOperand,
|
||||
ComparisonConditionType operatorType,
|
||||
IComparable rightOperand)
|
||||
{
|
||||
object? convertedOperand = null;
|
||||
|
||||
try
|
||||
{
|
||||
convertedOperand = Convert.ChangeType(rightOperand, leftOperand.GetType(), CultureInfo.CurrentCulture);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
}
|
||||
|
||||
if (convertedOperand == null)
|
||||
{
|
||||
return operatorType == ComparisonConditionType.NotEqual;
|
||||
}
|
||||
|
||||
int comparison = leftOperand.CompareTo((IComparable)convertedOperand);
|
||||
bool result = false;
|
||||
|
||||
switch (operatorType)
|
||||
{
|
||||
case ComparisonConditionType.Equal:
|
||||
result = comparison == 0;
|
||||
break;
|
||||
|
||||
case ComparisonConditionType.GreaterThan:
|
||||
result = comparison > 0;
|
||||
break;
|
||||
|
||||
case ComparisonConditionType.GreaterThanOrEqual:
|
||||
result = comparison >= 0;
|
||||
break;
|
||||
|
||||
case ComparisonConditionType.LessThan:
|
||||
result = comparison < 0;
|
||||
break;
|
||||
|
||||
case ComparisonConditionType.LessThanOrEqual:
|
||||
result = comparison <= 0;
|
||||
break;
|
||||
|
||||
case ComparisonConditionType.NotEqual:
|
||||
result = comparison != 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Markup;
|
||||
using Microsoft.Xaml.Interactivity;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.UI.WinUI;
|
||||
|
||||
[ContentProperty(Name = nameof(Actions))]
|
||||
public class ConditionAction :
|
||||
DependencyObject,
|
||||
IAction
|
||||
{
|
||||
public static readonly DependencyProperty ActionsProperty =
|
||||
DependencyProperty.Register(nameof(Actions),
|
||||
typeof(ActionCollection), typeof(ConditionAction),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public static readonly DependencyProperty ConditionProperty =
|
||||
DependencyProperty.Register(nameof(Condition),
|
||||
typeof(ICondition), typeof(ConditionAction),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
private ActionCollection? actions;
|
||||
|
||||
public ActionCollection Actions => actions ??= [];
|
||||
|
||||
public ICondition? Condition
|
||||
{
|
||||
get => (ICondition?)GetValue(ConditionProperty);
|
||||
set => SetValue(ConditionProperty, value);
|
||||
}
|
||||
|
||||
public object? Execute(object? sender, object? parameter)
|
||||
{
|
||||
if (Condition?.Evaluate() == true)
|
||||
{
|
||||
Interaction.ExecuteActions(sender, Actions, parameter);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Toolkit.UI.WinUI;
|
||||
|
||||
public class ConditionCollection :
|
||||
ObservableCollection<ComparisonCondition>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Markup;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.UI.WinUI;
|
||||
|
||||
[ContentProperty(Name = nameof(Conditions))]
|
||||
public class ConditionalExpression :
|
||||
DependencyObject,
|
||||
ICondition
|
||||
{
|
||||
public static readonly DependencyProperty ConditionsProperty =
|
||||
DependencyProperty.Register(nameof(Conditions),
|
||||
typeof(ConditionCollection), typeof(ConditionalExpression),
|
||||
new PropertyMetadata(new ConditionCollection()));
|
||||
|
||||
public static readonly DependencyProperty ForwardChainingProperty =
|
||||
DependencyProperty.Register(nameof(ForwardChaining),
|
||||
typeof(ForwardChaining), typeof(ConditionalExpression),
|
||||
new PropertyMetadata(ForwardChaining.And));
|
||||
|
||||
public ConditionalExpression()
|
||||
{
|
||||
SetValue(ConditionsProperty, new ConditionCollection());
|
||||
}
|
||||
|
||||
public ConditionCollection Conditions =>
|
||||
(ConditionCollection)GetValue(ConditionsProperty);
|
||||
|
||||
public ForwardChaining ForwardChaining
|
||||
{
|
||||
get => (ForwardChaining)GetValue(ForwardChainingProperty);
|
||||
set => SetValue(ForwardChainingProperty, value);
|
||||
}
|
||||
|
||||
public bool Evaluate()
|
||||
{
|
||||
bool result = false;
|
||||
foreach (var operation in Conditions)
|
||||
{
|
||||
result = operation.Evaluate();
|
||||
|
||||
if (!result && ForwardChaining == ForwardChaining.And)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result && ForwardChaining == ForwardChaining.Or)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user