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

  • 相关阅读:
    leetcode 279. Perfect Squares
    leetcode 546. Remove Boxes
    leetcode 312. Burst Balloons
    leetcode 160. Intersection of Two Linked Lists
    leetcode 55. Jump Game
    剑指offer 滑动窗口的最大值
    剑指offer 剪绳子
    剑指offer 字符流中第一个不重复的字符
    leetcode 673. Number of Longest Increasing Subsequence
    leetcode 75. Sort Colors (荷兰三色旗问题)
  • 原文地址:https://www.cnblogs.com/Dincat/p/13431049.html
Copyright © 2011-2022 走看看