加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

扩展UltraGrid控件实现对所有数据行的全选功能[Source Code下载]

发布时间:2020-12-16 09:10:40 所属栏目:asp.Net 来源:网络整理
导读:在前面一篇文章中,我通过对三种Infragistics 控件(UltraToolBarManager、UltraGird和UltraListView)进行扩展,以实现对ToolTip样式的定义,今天我来介绍如何采用相同的方式实现另外一个更为常用的功能:在UltraGrid的Header中动态添加CheckBox,从而实现

在前面一篇文章中,我通过对三种Infragistics 控件(UltraToolBarManager、UltraGird和UltraListView)进行扩展,以实现对ToolTip样式的定义,今天我来介绍如何采用相同的方式实现另外一个更为常用的功能:在UltraGrid的Header中动态添加CheckBox,从而实现对所有数据行进行全选的功能。[Source Code从这里下载]

一、我们的目标:在UltraGird的选择列的Header添加CheckBox实现对所有数据行的全选?

我们现有的绝大部分UltraGird都具有如下图(点击查看大图)所示的结构:第一行为UnBound列,单元格中的CheckBox用于对当前行的选择,即通过勾选相应的CheckBox代表选中某一行。现在的新的要求是:在CheckBox列的列头添加一个总的CheckBox,用于选中所有数据行,即当勾选CheckBox时,下面所有数据行对应的均自动被勾选,反之,解除现有数据行对应的CheckBox的勾选状态。

熟悉Infragistics控件的朋友应该知道,UltraGird具有一个很有用的动态分局的特性:你可以将可被用于分组的列通过鼠标拖到最上方的区域(Drag a column header here to group by the column),那么UltraGird会自动为你将所有的数据行按照该列的值进行动态分组。这个分组功能为我们要扩展的UltraGird又增加了一个新的特性:如果在分组状态,需要在每一个分组行中添加CheckBox,该CheckBox用于对当前组范围内所有数据行的全选。最后的效果如右图(点击查看大图)所示。

二、关于UIElement和UIElementCreationFilter

在具体介绍实现的之前,我们先来谈谈相关的一些背景知识:关于UIElement和UIElementFilter。Infragistics 基于Windows Forms应用的控件具有非常高的扩展型。通过合理使用UIElement,开发者可以很容易地添加一些现有控件没有提供的功能。

基本上所有的Infragistics 控件(这里我们仅仅指基于Window Forms应用控件)都有一个具有层级关系的UIElement组成。比如,一个UltraTree 由一个UltraTreeUIElement构成,而一个UltraTreeUIElement又包含一组TreeNodeUIElement 对象和NodeConnectorUIElement对象。而TreeNodeUIElements又由一组PreNodeAreaUIElement 和NodeSelectableAreaUIElement组成。对于NodeSelectableAreaUIElements,其组成元素又包含两种:ExpansionIndicatorUIElements 和NodeTexUIElements。

所有的UIElement相关的操作,比如改变其显示风格和位置,可以通过两个Filter对象控制,即CreationFilter和DrawFilter。而CreationFilter还能用于为现有控件动态的添加或者移除子控件,我们将要实现的对于CheckBox的动态添加就是通过自定义CreationFilter实现的。

三、自定义UIElementCreationFilter实现对CheckBox的动态添加

对现有UltraGrid的扩展的核心在于自定义UIElementCreationFilter实现对CheckBox的动态添加,在具体介绍如何自定义UIElementCreationFilter之前,我们先看看我们扩展出来的UltraGrid的定义。从下面的代码片段可以看出,扩展控件ExtendedUltraGrid的定义其实很简单。其中,SelectAllColumnName表示CheckBox列的名称;而IsGroupMode属性表示当前是否处于分组模式;CheckState表示在未分组情况下Select-All CheckBox应有的状态;在构造函数中,我们指定了UltraGrid的CreationFilter属性。

   1: using System.Windows.Forms;
   3:? 
   5: {
   7:     {
   9:? 
  11:         {
  13:             {
  15:                 {
  17:                     {
  19:                     }
  21:                 false;
  23:         }
  25:         internal CheckState CheckState{ get; set; }
  27:         public ExtendedUltraGrid()
  29:             this.CreationFilter = new CheckableHeaderCreationFilter(this);
  31:     }
  
class MyUltraExplorerBarCreationFilter : IUIElementCreationFilter
   4:     void AfterCreateChildElements(UIElement parent)
   6:         // called for a UIElement (parent) after it creates its child elements.
   8:     bool BeforeCreateChildElements(UIElement parent)
// called for a UIElement (parent) before it creates its child elements.
  13: }

在CheckableHeaderCreationFilter中,我们将在Select列的列头添加CheckBox的操作实现在AfterCreateChildElements方法中。其主要的逻辑是:通过parent的类型(必须是HeaderUIElement)、Column的类型(比如是Boolean)和Column Name(必须是在ExtendedUltraGrid的SelectAllColumnName属性指定)确定parent正是我们需要位置添加Check子控件的UIElement。然后创建CheckBoxUIElement,并将其添加到parent中,并通过Rect属性确定其显示的位置。然后我们会根据分组行(UltraGridGroupByRow)的Tag(这个会在自定义CheckBoxUIElement中设置)设置新创建的CheckBoxUIElement的CheckState状态,如果没有在分组模式下,我们根据ExtendedUltraGrid的CheckState属性指定该CheckBoxUIElement的状态。

using System.Collections.Generic;
using System.Windows.Forms;
   8:    9: {
  11:     {
  13:         { get; private set; }
  15:         public CheckableHeaderCreationFilter( ExtendedUltraGrid control)
  17:             if (null == control)
  19:                 throw new ArgumentNullException("control");
  21:             this.Control = control;
  23:? 
  26:             //Filter the HeaderUIElement element.
  28:             null == headerUIElement)
  30:                 return;
  32:? 
  34:             if (headerUIElement.Header.Column.DataType != typeof(bool) || headerUIElement.Header.Column.Key != this.Control.SelectAllColumnName)
  36:                   37:             }
  39:             //Check the exitence of CheckBoxUIElement.
  41:             CheckBoxUIElement checkBoxUIElement = parent.GetDescendant(typeof(CheckBoxUIElement)) as CheckBoxUIElement;
  43:             {
  45:             }
  47:             parent.ChildElements.Add(checkBoxUIElement);
  49:                         parent.Rect.X + (parent.Rect.Width - checkBoxUIElement.CheckSize.Width) / 2 + 1,
  51:                         checkBoxUIElement.CheckSize.Width,1)" id="lnum52">  52:                         checkBoxUIElement.CheckSize.Height
  54:             //For GroupRow,set the Tag as the current CheckState.
  56:             UltraGridGroupByRow parentRow = ultraGridRow.ParentRow as UltraGridGroupByRow;
  58:             {
  60:             }
  62:             if (!this.Control.IsGroupMode)
  64:                 checkBoxUIElement.CheckState = this.Control.CheckState;
  66:         }
  68:           69:         {
  71:         }
  73: }

四、自定义CheckBoxUIElement

从CheckableHeaderCreationFilter的定义我们可以看到:动态添加的CheckBoxUIElement的类型为ExtendedCheckBoxUIElement,这是我们自定义的类型。我们通过该类型来设置分组行或者整个UltraGrid(没有在分组模式下)应有的状态,并最终对相应的数据行(在分组模式下为当前分组的所有行,而没有分组情况下为整个UltraGrid的所有行)的Check状态。所有的实现具有体现在重写的OnCheckStateChange上面。

using Infragistics.Win.UltraWinGrid;
namespace Artech.ExtendedUltraGrid4SelectAll
   7:     class ExtendedCheckBoxUIElement : CheckBoxUIElement
   9:         public ExtendedCheckBoxUIElement(UIElement parent)
  12:             this.ThreeState =   13:         }
  16:         {
base.CheckState;
  22:             {
  24:                 base.CheckState = value;
  26:                 {
  28:                 }
  30:         }
  32:         protected override void OnCheckStateChange()
base.OnCheckStateChange();
  36:             HeaderUIElement headerUIElement = this.GetAncestor(typeof(HeaderUIElement))as HeaderUIElement;
  40:             {
  43:             }
  45:             {
  48:? 
  50:             {
  53:         }
  55:         private void SetAllGridRowSelected(RowsCollection rows,CheckState state)
in rows)
  60:                 {
  63:                 }
  66:                     string selectAllColumnName = (as ExtendedUltraGrid).SelectAllColumnName;
  68:                     if (!row.Band.Columns.Exists(selectAllColumnName)) continue;
  72:                     row.Update();
  74:             }
  76:     }