zoukankan      html  css  js  c++  java
  • DataGridView过滤弹出

    介绍 我一直在寻找一种简单而灵活的网格过滤机制,用于新老应用程序。我没有找到完全满足我需要的现成的解决方案。因此,我决定创建自己的过滤库。我试图达到的目标是: 易于集成:使用“几行代码”来满足快速集成的需要。用户友好:好看的外观,容易使用。不是普遍的代码:使用DataGridView派生会约束人们重新声明他们的实例。此外,这可能与现有的网格衍生相冲突。灵活:世界上从来没有足够的过滤器! 使用的代码 这是为渴望的人准备的。承诺的“几行代码”只是其中之一。将dgvfilterpop .dll添加到您的引用中。在某处这样写一行字: 隐藏,复制Code

    DgvFilterManager filterManager = new DgvFilterManager(dataGridView1);

    这是所有。您的网格现在能够过滤列值。右键单击列标题,可以看到一个弹出窗口,根据所单击的列数据类型显示不同的过滤特性。 注意:您的网格必须数据绑定到DataView、DataTable或解析为这两者之一的BindingSource。 类体系结构 下面的图中展示了三个主要的类: DgvFilterManager类 DgvFilterManager类不提供用户界面。它的工作是协调DataGridView和视觉过滤元素之间的交互。当您将DataGridView分配给DgvFilterManager时,后者会附加一些处理程序来响应列标题上的右键,并在网格上执行一些自定义绘制。当用户右键单击列标头时,DgvFilterManager会在列附近弹出一个窗口。这个弹出窗口是一个控件,它充当其他控件的主机,每个控件对应一个列。根据单击的列,一次只能看到这些子控件中的一个。我们有一个过滤器主机控件和许多列过滤器子控件。 筛选器主机控件必须是DgvBaseFilterHost类的派生,而筛选器控件必须从DgvBaseColumnFilter类派生。这两个类本身不提供任何用户界面。 默认,DgvFilterManager使用标准主机实现,名叫DgvFilterHost,根据每一列类型和数据类型,一个过滤标准实现的(见下文):DgvTextBoxColumnFilter, DgvCheckBoxColumnFilter, DgvComboBoxColumnFilter或DgvDateColumnFilter。 当DataGridView附加到manager时,后者执行以下操作: 它创建了一个过滤器主机,它是DgvFilterHost类的一个实例。如果已经提供了筛选器主机,则跳过此步骤。它创建一个DgvBaseColumnFilters列表,每列一个,并将每个元素初始化为DgvBaseColumnFilter的专门化。如果AutoCreateFilters为false,则跳过此步骤。 您可以为某个列强制指定特定的列筛选器类型,并通过columnfilteradded事件干预此过程。在自动创建过程之后,您还可以进行干预,通过管理器提供的两个索引器之一访问过滤器实例,并用用户选择的实例替换它们。 DgvBaseFilterHost类 筛选器主机控件的目的是在右击列附近显示弹出窗口,并托管子列筛选器控件。当显示弹出窗口时,只有与右击列相关的列过滤器控件是可见的。DgvBaseFilterHost是UserControl的派生,提供了与DgvFilterManager协作的功能。 注意:这个类被用作一个抽象类。但是,在设计派生类时,将其声明为抽象会在设计器中生成错误。 在您的派生中,您必须提供一个主机区域(例如面板)并覆盖FilterClientArea以返回它。同样,为移除过滤器,移除所有过滤器,应用过滤器创建视觉元素,并使用DgvFilterManager方法ActivateFilter和ActivateAllFilters使它们活起来。 DgvBaseColumnFilter类 列筛选器控件的目的是包含可视元素,允许最终用户构造筛选器。在继承它时,您可以像创建任何其他用户控件一样工作。这个类是UserControl的派生,提供了与DgvFilterManager协作的功能。 注意:这个类被用作一个抽象类。但是,在设计派生类时,将其声明为抽象会在设计器中生成错误。 您应该重写OnFilterExpressionBuilding,以提供一个过滤器表达式构造逻辑,并设置过滤器表达式和过滤器标题属性的值。 标准实现 DgvFilterHost类 这是DgvBaseFilterHost的标准实现。这个类没有什么特别的。大部分逻辑在它的基类中。它只包含诸如按钮和图形之类的视觉元素,以及充当clien的面板用于子列筛选器控件的区域。 DgvTextBoxColumnFilter类 这是DgvBaseColumnFilter标准实现之一。它由一个包含操作符列表的combobox和一个要在其中键入过滤器值的文本框组成。这个列过滤器默认用于DataGridViewTextBoxColumns,除非绑定的数据类型是DateTime。字符串类型和数值类型之间可用的操作符列表是不同的。 DgvTextBoxColumnFilter类 筛选复选框列的标准实现。唯一可用的操作符是equal和一般的null和not null操作符。 DgvDateColumnFilter类 日期列筛选的标准实现。 DgvComboBoxColumnFilter类 过滤combobox列的标准实现。默认情况下,在文本框列,过滤器管理器使用DgvTextBoxColumnFilter实例。但是,您可以在这些列上强制使用DgvComboBoxColumnFilter实例。在本例中,DgvComboBoxColumnFilter实例自动从列数据创建一个不同的值列表。当底层数据发生更改时,应该显式调用RefreshValues()方法。 定制 如果“一行使用”不能满足您的需要,您可以以不同的方式控制添加和显示过滤器的过程。 对非组合框列使用DgvComboBoxColumnFilter 使用一个管理器索引器来访问过滤器,并为它分配一个DgvComboBoxColumnFilter类的实例。 隐藏,复制Code

    DgvFilterManager fm = new DgvFilterManager(dataGridView1);
    fm["CustomerID"] = new DgvComboBoxColumnFilter();

    使用事件 ColumnFilterAdding 使用此管理器事件,您可以在管理器创建预定义筛选器之前强制使用首选筛选器。当您设置DataGridView属性时,该事件将针对网格中的每一列引发。 隐藏,复制Code

      ...
      DgvFilterManager fm = new DgvFilterManager();
      fm.ColumnFilterAdding += new ColumnFilterEventHandler(fm_ColumnFilterAdding);
      fm.DataGridView = dataGridView1; // this raises ColumnFilterAdding events
      ...
    
    void fm_ColumnFilterAdding(object sender, ColumnFilterEventArgs e) {
      if (e.Column.Name == "CustomerID") {
        e.ColumnFilter = new DgvComboBoxColumnFilter();
      }
    }

    PopupShowing 此管理器事件允许您在弹出时自定义筛选器主机位置。 隐藏,复制Code

      ...
      DgvFilterManager fm = new DgvFilterManager();
      fm.DataGridView = dataGridView1;
      // Customize the popup positioning.
      fm.PopupShowing += new ColumnFilterEventHandler(fm_PopupShowing);
      ...
    
    void fm_PopupShowing(object sender, ColumnFilterEventArgs e) {
      DgvFilterManager fm = ((DgvFilterManager)sender);
      Rectangle HeaderRectangle = 
        fm.DataGridView.GetCellDisplayRectangle(e.Column.Index,-1,true);
      //Show the popup under the column header
      fm.FilterHost.Popup.Show(fm.DataGridView, HeaderRectangle.Left, 
                               HeaderRectangle.Bottom);
      e.Handled = true;
    }

    FilterExpressionBuilding 使用DgvBaseColumnFilter事件,您可以自定义筛选器表达式构建过程。在下面的代码示例中,我们添加了新的操作符,然后在事件处理程序中管理它们。管理器将使用FilterExpression和FilterCaption属性来构建整个过滤器和设置列标题。 隐藏,收缩,复制Code

      ...
      DgvDateColumnFilter OrderDate;
      ...
      DgvFilterManager fm = new DgvFilterManager(dataGridView1);
      fm.DataGridView = dataGridView1; //after this line, column filters are created
    
      // Get the created column filter for OrderDate column
      OrderDate = ((DgvDateColumnFilter)fm["OrderDate"]);
    
      //Add some new operators
      OrderDate.ComboBoxOperator.Items.Insert(0, "This year");
      OrderDate.ComboBoxOperator.Items.Insert(1, "1 year ago");
      OrderDate.ComboBoxOperator.Items.Insert(2, "2 years ago");
    
      //Add an handler
      OrderDate.FilterExpressionBuilding += 
        new CancelEventHandler(OrderDate_FilterExpressionBuilding);
      
      ...
      
    void OrderDate_FilterExpressionBuilding(object sender, CancelEventArgs e) {
      int index = OrderDate.ComboBoxOperator.SelectedIndex;
      if (index < 3) { // the first 3 are the new operators
        int year = (DateTime.Today.Year - index);
        OrderDate.FilterExpression = "(OrderDate>='" + year.ToString() + "-1-1' " 
                                   + "AND OrderDate<='" + year.ToString() + "-12-31') ";
        OrderDate.FilterCaption = OrderDate.OriginalDataGridViewColumnHeaderText 
                                + "\n = year " + year.ToString();
        e.Cancel = true;
      }
    }

    子类化 定制过滤器的一种更强大的方法是通过子类化。您应该将DgvBaseFilterHost和DgvBaseColumnFilter的拟议标准实现看作是一些可能的实现。 创建自己的主机 如前所述,从DgvBaseFilterHost派生并提供一些可视化元素。在您的控件中添加一个容器来承载子筛选器控件,并通过覆盖FilterClientArea属性返回它。基类提供了与管理器协作所需的逻辑,并提供了一些帮助定位子筛选器控件和调整主机大小的工具。另一个工具简化了透明皮肤主机的创建,这要感谢我在John O'Byrne的一篇非常好的文章中找到的方法BitmapToRegion。 注意:带皮肤的主机必须限制为固定大小。一定要通过覆盖DoAutoFit方法来禁止大小调整逻辑。另外,在设计您自己的主机和过滤器时,请记住这个限制。 隐藏,复制Code

    DgvFilterManager fm = new DgvFilterManager();
    fm.FilterHost = new CustomizedFilterHost();
    fm.DataGridView = dataGridView1;

    创建自己的列过滤器 创建新的列过滤器很简单。从DgvBaseColumnFilter派生并添加您的视觉元素。重写OnFilterExpressionBuilding以提供过滤器构建逻辑,并使用DataView。RowFilter规则,为FilterExpression属性分配一个值,为FilterCaption属性分配一个标题。 请记住,过滤器是在用户单击主机的OK按钮时应用的。但是,您可以获得一个即时筛选应用程序,该应用程序调用筛选器的RebuildFilter方法。 新过滤器 为了满足一些请求,在1.1.0.0更新中,我引入了三种新的过滤器实现: DgvMonthYearColumnFilter类 这个过滤器允许用户选择一个月和一年。通过设置YearMin和YearMax属性,您可以控制显示的年份范围。月份名称默认为英文,但是您可以通过使用逗号分隔的月份名称列表设置静态属性MonthCsvList的一次值来提供特定文化的名称。 DgvNumRangeColumnFilter类 使用此筛选器可允许用户在数值列上指定范围筛选器。 DgvDateRangeColumnFilter类 使用此筛选器可允许用户对日期列指定范围筛选器。 结论 在本文中,我介绍了类体系结构和常见的使用场景。我希望这个概念性的概述能帮助您理解它是如何工作的。有关详细的说明和参考资料,请参阅所附的文档。 注:对于那些对记录他们的作品感兴趣的人,我有我们艾德·这些材料: 来自MSDNSandcastle v2.4.10520的XML文档注释:来自MicrosoftHelp File Builder 1.8.0.1的文档命令行编译器Beta:来自Eric Woodruff的一个Sandcastle GUI(需要。net 3.5) 历史 1.1.0.0(二零零九年三月十九日) 添加了三个新的嵌入式过滤器:DgvDateRangeColumnFilter, DgvMonthYearColumnFilter和DgvNumRangeColumnFilter。现在可以动态更改数据源了。 1.0.0.1(2009年3月4日) 修正:当网格绑定到使用数据集作为第一个源的BindingSource时,过滤器将被应用。 1.0.0.0(2009年3月1日) 最初的版本。 本文转载于:http://www.diyabc.com/frontweb/news187.html

  • 相关阅读:
    html+vue.js 实现分页可兼容IE
    Display、Visibility 和 Opacity 的区别
    Vue项目刷新页面 IE/360 浏览器 input输入框不清空问题处理
    Webpack入门
    linux下Tomcat日志文件catalina.out的切割
    无监控,不运维
    windows与linux下jdk+tomcat安裝
    java面向对象(提高篇)
    java面向对象(汇总)
    JAVA工程师简历模板
  • 原文地址:https://www.cnblogs.com/Dincat/p/13431049.html
Copyright © 2011-2022 走看看