创建用于DataGrid的过滤器类结构

时间:2014-07-10 02:04:23

标签: c# wpf datagrid filtering

我正在尝试为DataGrid创建一个弹出窗口过滤器。我的目标是使用弹出窗口,允许用户添加多个过滤规则。我还没有完全弄清楚UI,但下面是一个模型。

它将提供添加多个规则“And”或“Ör”以及括号的某种类型的图形表示(我刚刚用一些垂直线绘制)。

enter image description here

我已经启动了以下过滤器类结构。我们的想法是拥有一组列定义,每个列都有一个对象集合,可以是单独的过滤器或过滤器集合(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;
}

1 个答案:

答案 0 :(得分:1)

我尝试创建一个类似的过滤器,其中包含无限深度的过滤器和组

result

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; }

您可以根据需要调整所有内容