我正在尝试为DataGrid创建一个弹出窗口过滤器。我的目标是使用弹出窗口,允许用户添加多个过滤规则。我还没有完全弄清楚UI,但下面是一个模型。
它将提供添加多个规则“And”或“Ör”以及括号的某种类型的图形表示(我刚刚用一些垂直线绘制)。
我已经启动了以下过滤器类结构。我们的想法是拥有一组列定义,每个列都有一个对象集合,可以是单独的过滤器或过滤器集合(FilterGroup),也可以为括号提供层次结构。
我无法弄清楚的是:如何以及在何处适应条件运算符“And”和“Or”,这也是提供括号和聚合的好方法。期待提出意见和建议。
static class SomeStaticClass
{
static List<PropertyFilter> PropertyFilters = new List<PropertyFilter>();
}
public class PropertyFilter
{
string PropertyName = "";
Type PorpertyType = null;
DataGridColumn ColumnType = null;
List<object> FilterCollection = new List<object>();
}
public enum ComparisonOperator
{
Equals,
Contains,
StartsWith,
EndsWith
}
public enum ConditionalOperator
{
And,
Or
}
public class FilterGroup
{
List<object> FilterCollection = new List<object>();
}
public class Filter
{
ComparisonOperator op_comp;
string value;
bool matchCase;
}
答案 0 :(得分:1)
我尝试创建一个类似的过滤器,其中包含无限深度的过滤器和组
类
namespace CSharpWPF
{
public abstract class BaseFilter
{
//public abstract bool ApplyFilter();
}
public class PropertyFilter : BaseFilter
{
public string PropertyName { get; set; }
public Type PropertyType { get; set; }
public ConditionalOperator Operator { get; set; }
public Filter Filter { get; set; }
}
public class FilterGroup : BaseFilter
{
public FilterGroup()
{
Filters = new List<BaseFilter>();
}
public ConditionalOperator? Operator { get; set; }
public List<BaseFilter> Filters { get; set; }
}
public enum ComparisonOperator
{
Equals,
Contains,
StartsWith,
EndsWith
}
public enum ConditionalOperator
{
And,
Or
}
public class Filter
{
public ComparisonOperator Operator { get; set; }
public string Value { get; set; }
public bool MatchCase { get; set; }
}
}
XAML
<ScrollViewer>
<StackPanel>
<ContentControl xmlns:l="clr-namespace:CSharpWPF"
Content="{Binding Filter}">
<ContentControl.Resources>
<ObjectDataProvider x:Key="operators"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="l:ConditionalOperator" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<DataTemplate DataType="{x:Type l:PropertyFilter}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"
SharedSizeGroup="name" />
<ColumnDefinition Width="auto"
SharedSizeGroup="match" />
<ColumnDefinition />
<ColumnDefinition Width="auto"
SharedSizeGroup="button" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding PropertyName}"
Margin="2" />
<CheckBox IsChecked="{Binding Filter.MatchCase}"
VerticalAlignment="Center"
Content="Aa"
Margin="2"
Grid.Column="1" />
<TextBox Text="{Binding Filter.Value}"
Grid.Column="2"
Margin="2" />
<Button Content="X"
Padding="0"
Grid.Column="3"
Margin="2" />
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type l:FilterGroup}">
<Border BorderBrush="DarkGreen"
BorderThickness="4,1,1,1"
Margin="4,1,1,1"
Padding="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ComboBox x:Name="operator"
SelectedItem="{Binding Operator}"
VerticalAlignment="Center"
Margin="2"
ItemsSource="{Binding Source={StaticResource operators}}" />
<ItemsControl ItemsSource="{Binding Filters}"
Grid.IsSharedSizeScope="True"
Grid.Column="1" />
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Operator}"
Value="{x:Null}">
<Setter TargetName="operator"
Property="Visibility"
Value="Collapsed" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</StackPanel>
</ScrollViewer>
示例代码
public ViewModel()
{
Filter = new FilterGroup();
Filter.Filters.Add(new PropertyFilter() { PropertyName = "Text", PropertyType = typeof(string) });
FilterGroup group = new FilterGroup() { Operator = ConditionalOperator.And };
group.Filters.Add(new PropertyFilter() { PropertyName = "Text2", PropertyType = typeof(string) });
group.Filters.Add(new PropertyFilter() { PropertyName = "Text3", PropertyType = typeof(string) });
Filter.Filters.Add(group);
group = new FilterGroup() { Operator = ConditionalOperator.Or };
group.Filters.Add(new PropertyFilter() { PropertyName = "Text4", PropertyType = typeof(string) });
group.Filters.Add(new PropertyFilter() { PropertyName = "Text5", PropertyType = typeof(string) });
FilterGroup subGroup = new FilterGroup() { Operator = ConditionalOperator.Or };
subGroup.Filters.Add(new PropertyFilter() { PropertyName = "Text8", PropertyType = typeof(string) });
subGroup.Filters.Add(new PropertyFilter() { PropertyName = "Text9", PropertyType = typeof(string) });
group.Filters.Add(subGroup);
Filter.Filters.Add(group);
Filter.Filters.Add(new PropertyFilter() { PropertyName = "Text6", PropertyType = typeof(string) });
Filter.Filters.Add(new PropertyFilter() { PropertyName = "Text7", PropertyType = typeof(string) });
}
public FilterGroup Filter { get; set; }
您可以根据需要调整所有内容