【问题标题】:Creating filter class structure for use with a DataGrid创建用于 DataGrid 的过滤器类结构
【发布时间】:2014-08-31 05:29:06
【问题描述】:

我正在尝试为 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;
}

【问题讨论】:

  • 很大的挑战,我会努力为你弄点东西的。

标签: c# wpf datagrid filtering


【解决方案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; }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2019-10-03
    • 2020-05-18
    • 1970-01-01
    • 2020-08-26
    相关资源
    最近更新 更多