|
@@ -6,7 +6,9 @@ using System.Reflection;
|
|
|
using System.Windows;
|
|
|
using System.Windows.Controls;
|
|
|
using System.Windows.Media;
|
|
|
+using ControlzEx.Standard;
|
|
|
using InABox.Core;
|
|
|
+using InABox.Wpf;
|
|
|
|
|
|
namespace InABox.DynamicGrid;
|
|
|
|
|
@@ -19,31 +21,37 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
private OperatorNode Operator;
|
|
|
private ValueNode Value;
|
|
|
private Border ValuePlaceHolder;
|
|
|
- private ConstantNode Constant;
|
|
|
+ private ConstantNode? Constant;
|
|
|
+ private ICustomValueNode? CustomValue;
|
|
|
private Button AndButton;
|
|
|
private Button OrButton;
|
|
|
private FilterNodeGrid<T> Ands;
|
|
|
private FilterNodeGrid<T> Ors;
|
|
|
|
|
|
+ private FilterEditorConfiguration Configuration;
|
|
|
+
|
|
|
private FilterNodeType filterType;
|
|
|
|
|
|
public delegate void RemoveEventHandler();
|
|
|
public event RemoveEventHandler? Remove;
|
|
|
|
|
|
- public FilterNode(Filter<T> filter, FilterNodeType filterType = FilterNodeType.ROOT)
|
|
|
+ public FilterNode(Filter<T> filter, FilterNodeType filterType = FilterNodeType.ROOT, FilterEditorConfiguration? configuration = null)
|
|
|
{
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
|
|
- ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
|
|
-
|
|
|
- RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto});
|
|
|
- RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto});
|
|
|
- RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto});
|
|
|
+ Configuration = configuration ?? FilterEditorConfiguration.Default();
|
|
|
+
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // Clear
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // Label
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // Property
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // Operator
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // Constant
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // CustomValue
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); // Value
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // And
|
|
|
+ ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // Or
|
|
|
+
|
|
|
+ RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto}); // Header
|
|
|
+ RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto}); // Ands
|
|
|
+ RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto}); // Ors
|
|
|
|
|
|
ClearButton = new Button { Content = "-", Width = 20, Margin = new Thickness(0, 0, 5, 0), Padding = new Thickness(5) };
|
|
|
|
|
@@ -74,10 +82,13 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
SetValueNode(valueNode ?? new EmptyValueNode(), filter.Value);
|
|
|
|
|
|
Constant = CreateConstantNode(Property.SelectedProperty, filter.Operator, filter.Value as FilterConstant?);
|
|
|
- ConstantChanged(Constant.SelectedConstant);
|
|
|
+ CheckValueVisibilities();
|
|
|
+
|
|
|
+ CustomValue = CreateCustomValueNode(Property.SelectedProperty, filter.Operator, filter.Value as CustomFilterValue);
|
|
|
+ CheckValueVisibilities();
|
|
|
|
|
|
- Ands = new FilterNodeGrid<T>(filter.Ands, FilterNodeType.AND) { Margin = new Thickness(0, 0, 0, 0) };
|
|
|
- Ors = new FilterNodeGrid<T>(filter.Ors, FilterNodeType.OR);
|
|
|
+ Ands = new FilterNodeGrid<T>(filter.Ands, FilterNodeType.AND, Configuration) { Margin = new Thickness(0, 0, 0, 0) };
|
|
|
+ Ors = new FilterNodeGrid<T>(filter.Ors, FilterNodeType.OR, Configuration);
|
|
|
|
|
|
AndButton = new Button { Content = "And", Width = 40, Margin = new Thickness(0, 0, 5, 0), Padding = new Thickness(5) };
|
|
|
OrButton = new Button { Content = "Or", Width = 40, Margin = new Thickness(0, 0, 0, 0), Padding = new Thickness(5) };
|
|
@@ -94,10 +105,17 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
}
|
|
|
Add(Property, 0, 2);
|
|
|
Add(Operator, 0, 3);
|
|
|
- Add(Constant, 0, 4);
|
|
|
- Add(ValuePlaceHolder, 0, 5);
|
|
|
- Add(AndButton, 0, 6);
|
|
|
- Add(OrButton, 0, 7);
|
|
|
+ if(Constant is not null)
|
|
|
+ {
|
|
|
+ Add(Constant, 0, 4);
|
|
|
+ }
|
|
|
+ if(CustomValue is not null)
|
|
|
+ {
|
|
|
+ Add(CustomValue.FrameworkElement, 0, 5);
|
|
|
+ }
|
|
|
+ Add(ValuePlaceHolder, 0, 6);
|
|
|
+ Add(AndButton, 0, 7);
|
|
|
+ Add(OrButton, 0, 8);
|
|
|
|
|
|
Add(Ands, 1, 1, 7);
|
|
|
Add(Ors, 2, 1, 7);
|
|
@@ -134,7 +152,7 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
var filter = new Filter<T>();
|
|
|
filter.Expression = CoreUtils.CreateMemberExpression(typeof(T), Property.SelectedProperty);
|
|
|
filter.Operator = Operator.SelectedOperator;
|
|
|
- filter.Value = Constant.SelectedConstant ?? Value.Value;
|
|
|
+ filter.Value = Constant?.SelectedConstant ?? CustomValue?.Value ?? Value.Value;
|
|
|
|
|
|
foreach(var and in Ands.GetFilters())
|
|
|
{
|
|
@@ -224,14 +242,12 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
Value = node;
|
|
|
Value.Value = value;
|
|
|
Value.Margin = new Thickness(0, 0, 5, 0);
|
|
|
- Add(Value, 0, 5);
|
|
|
- CheckValueVisibility();
|
|
|
+ Add(Value, 0, 6);
|
|
|
+ CheckValueVisibilities();
|
|
|
}
|
|
|
|
|
|
- private ConstantNode CreateConstantNode(string? propertyName, Operator op, FilterConstant? constantvalue)
|
|
|
+ private ConstantNode? CreateConstantNode(string? propertyName, Operator op, FilterConstant? constantvalue)
|
|
|
{
|
|
|
- var result = new ConstantNode();
|
|
|
-
|
|
|
var values = new Dictionary<string, FilterConstant?>();
|
|
|
if (!string.IsNullOrWhiteSpace(propertyName))
|
|
|
{
|
|
@@ -245,24 +261,53 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (!values.Any())
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ var result = new ConstantNode();
|
|
|
+
|
|
|
result.DisplayMemberPath = "Key";
|
|
|
result.SelectedValuePath = "Value";
|
|
|
result.ItemsSource = values;
|
|
|
result.SelectedConstant = constantvalue;
|
|
|
result.Margin = new Thickness(0, 0, 5, 0);
|
|
|
- result.Visibility = values.Any()
|
|
|
- ? Visibility.Visible
|
|
|
- : Visibility.Collapsed;
|
|
|
result.ConstantChanged += ConstantChanged;
|
|
|
return result;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ private ICustomValueNode? CreateCustomValueNode(string? propertyName, Operator op, CustomFilterValue? value)
|
|
|
+ {
|
|
|
+ if (!Configuration.HasCustomValue)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ var customValue = Configuration.CreateCustomValueNode(typeof(T), propertyName, op, value);
|
|
|
+ if(customValue is not null)
|
|
|
+ {
|
|
|
+ customValue.FrameworkElement.Margin = new Thickness(0, 0, 5, 0);
|
|
|
+ customValue.ValueChanged += CustomValue_ValueChanged;
|
|
|
+ }
|
|
|
+ return customValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void CustomValue_ValueChanged(ICustomValueNode sender, CustomFilterValue? value)
|
|
|
+ {
|
|
|
+ CheckValueVisibilities();
|
|
|
+ }
|
|
|
+
|
|
|
private void Property_PropertyChanged(string? property)
|
|
|
{
|
|
|
- Children.Remove(Constant);
|
|
|
+ if (Constant is not null)
|
|
|
+ {
|
|
|
+ Children.Remove(Constant);
|
|
|
+ }
|
|
|
Constant = CreateConstantNode(property, Operator.SelectedOperator, null);
|
|
|
- Add(Constant,0,4);
|
|
|
+ if(Constant is not null)
|
|
|
+ {
|
|
|
+ Add(Constant, 0, 4);
|
|
|
+ }
|
|
|
|
|
|
var value = Value.Value;
|
|
|
Children.Remove(Value);
|
|
@@ -274,14 +319,31 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
value
|
|
|
);
|
|
|
|
|
|
+ CustomFilterValue? customValue = null;
|
|
|
+ if(CustomValue is not null)
|
|
|
+ {
|
|
|
+ customValue = CustomValue.Value;
|
|
|
+ Children.Remove(CustomValue.FrameworkElement);
|
|
|
+ }
|
|
|
+ CustomValue = CreateCustomValueNode(property, Operator.SelectedOperator, customValue);
|
|
|
+ if (CustomValue is not null)
|
|
|
+ {
|
|
|
+ Add(CustomValue.FrameworkElement, 0, 5);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void Operator_OperatorChanged(Operator op)
|
|
|
{
|
|
|
|
|
|
- Children.Remove(Constant);
|
|
|
+ if (Constant is not null)
|
|
|
+ {
|
|
|
+ Children.Remove(Constant);
|
|
|
+ }
|
|
|
Constant = CreateConstantNode(Property.SelectedProperty, Operator.SelectedOperator, null);
|
|
|
- Add(Constant,0,4);
|
|
|
+ if (Constant is not null)
|
|
|
+ {
|
|
|
+ Add(Constant, 0, 4);
|
|
|
+ }
|
|
|
|
|
|
var value = Value.Value;
|
|
|
Children.Remove(Value);
|
|
@@ -299,17 +361,44 @@ public class FilterNode<T> : BaseFilterNode
|
|
|
|
|
|
private void ConstantChanged(FilterConstant? constant)
|
|
|
{
|
|
|
- CheckValueVisibility();
|
|
|
+ CheckValueVisibilities();
|
|
|
}
|
|
|
|
|
|
- private void CheckValueVisibility()
|
|
|
+ private void CheckValueVisibilities()
|
|
|
{
|
|
|
- Value.Visibility = (Constant?.SelectedConstant == null) && Value is not EmptyValueNode
|
|
|
- ? Visibility.Visible
|
|
|
- : Visibility.Collapsed;
|
|
|
- ValuePlaceHolder.Visibility = (Constant?.SelectedConstant != null) || (Value is EmptyValueNode)
|
|
|
- ? Visibility.Visible
|
|
|
- : Visibility.Collapsed;
|
|
|
+ if(Constant?.SelectedConstant != null)
|
|
|
+ {
|
|
|
+ Value.Visibility = Visibility.Collapsed;
|
|
|
+ ValuePlaceHolder.Visibility = Visibility.Visible;
|
|
|
+ Constant.Visibility = Visibility.Visible;
|
|
|
+ if(CustomValue is not null)
|
|
|
+ {
|
|
|
+ CustomValue.FrameworkElement.Visibility = Visibility.Collapsed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(CustomValue?.Value != null)
|
|
|
+ {
|
|
|
+ Value.Visibility = Visibility.Collapsed;
|
|
|
+ ValuePlaceHolder.Visibility = Visibility.Visible;
|
|
|
+ if(Constant is not null)
|
|
|
+ {
|
|
|
+ Constant.Visibility = Visibility.Collapsed;
|
|
|
+ }
|
|
|
+ CustomValue.FrameworkElement.Visibility = Visibility.Visible;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Value.Visibility = Visibility.Visible;
|
|
|
+ ValuePlaceHolder.Visibility = Visibility.Collapsed;
|
|
|
+ if (Constant is not null)
|
|
|
+ {
|
|
|
+ Constant.Visibility = Visibility.Visible;
|
|
|
+ }
|
|
|
+ if (CustomValue is not null)
|
|
|
+ {
|
|
|
+ CustomValue.FrameworkElement.Visibility = Visibility.Visible;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void Add(UIElement element, int row, int column = 1, int columnSpan = 1)
|