在WinForms和WebForms程序中,我们使用表格控件时经常会有这样的需求:如果这一列的单元格时CheckBox类型,我们希望在列头也添加一个CheckBox,通过对列头CheckBox的操作来完成对该列所有CheckBox的选中/不选中操作。下面我们就来看一看在C1FlexGrid for Silverlight中如何实现这一功能。
功能要求:
- 当对列头中的CheckBox进行选中操作时,这一列中所有的CheckBox将被选中
- 当对列头中的CheckBox进行不选中操作时,这一列中所有的CheckBox将不被选中
- 当这一列中所有CheckBox都被选中时,列头中的CheckBox也应该是选中状态
- 当这一列中所有CheckBox都不被选中时,列头中的CheckBox也应该是不选中状态
实现步骤:
第一步:设置数据源,我们以个人信息作为FlexGrid的数据源,代码如下:
public class Person : INotifyPropertyChanged { private int id; private string fname; private string lname; private bool present; public event PropertyChangedEventHandler PropertyChanged; public int ID { get { return id; } set { id = value; OnPropertyChanged("ID"); } } public string FName { get { return fname; } set { fname = value; OnPropertyChanged("FName"); } } public string LName { get { return lname; } set { lname = value; OnPropertyChanged("LName"); } } public bool Present { get { return present; } set { present = value; OnPropertyChanged("Present"); } } protected void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } } } 复制代码
List<Person> datasource = new List<Person>(); #region "Test Data" datasource.Add(new Person() { ID = 1, FName = "Robert", LName = "Ludlum", Present = true }); datasource.Add(new Person() { ID = 2, FName = "Tom", LName = "Clancy", Present = true }); datasource.Add(new Person() { ID = 3, FName = "Frederick", LName = "Forsyth", Present = false }); datasource.Add(new Person() { ID = 4, FName = "Dan", LName = "Brown", Present = true }); datasource.Add(new Person() { ID = 5, FName = "Paulo", LName = "Coelho", Present = false }); datasource.Add(new Person() { ID = 6, FName = "John", LName = "Grisham", Present = false }); #endregion this.c1FlexGrid1.ItemsSource = datasource; 复制代码
第二步:设置XAML中FlexGrid各个列的数据绑定信息
<Grid x:Name="LayoutRoot" Background="White"> <my:C1FlexGrid Name="c1FlexGrid1" AutoGenerateColumns="False"> <my:C1FlexGrid.Columns> <my:Column Header="ID" Binding="{Binding ID, Mode=OneWay}"/> <my:Column Header="First Name" Binding="{Binding FName, Mode=TwoWay}"/> <my:Column Header="Last Name" Binding="{Binding LName, Mode=TwoWay}"/> <my:Column Header="Present" Binding="{Binding Present, Mode=TwoWay}"> </my:Column> </my:C1FlexGrid.Columns> </my:C1FlexGrid> </Grid> 复制代码
第三步:实现选择/不选择的行为
为了在boolean类型的列中添加CheckBox功能,需要实现用户自定义的C1.Silverlight.FlexGrid.CellFactory类,在CheckBox类型的列中,我们需要处理以下操作:
1. 选择/不选择列头中的CheckBox控件
2. 选择/不选择单元格中的CheckBox控件
下面的代码重写了CreateColumnHeaderContent方法,以此来创建列头中的CheckBox控件,并通过CheckBox的Click事件来改变其选中和不选中状态:
//实现列头中的CheckBox功能 public override void CreateColumnHeaderContent(C1.Silverlight.FlexGrid.C1FlexGrid grid, Border bdr, C1.Silverlight.FlexGrid.CellRange range) { base.CreateColumnHeaderContent(grid, bdr, range); if (grid.Columns[range.Column].DataType == typeof(Boolean)) { chk = new CheckBox(); chk.Content = "Present"; bdr.Child = chk; parentgrid = grid; parentrange = range; // 添加Click事件,处理其选择/不选择状态 chk.Click += new RoutedEventHandler(chk_Click); } } void chk_Click(object sender, RoutedEventArgs e) { //如果列头中的CheckBox为选中状态,就设置该列中所有CheckBox为选中状态 if ((sender as CheckBox).IsChecked == true) { for (int i = 0; i <= parentgrid.Rows.Count - 1; i++) { parentgrid[i, parentrange.Column] = true; } } else //如果列头中的CheckBox为不选中状态,就设置该列中所有CheckBox为不选中状态 { for (int i = 0; i <= parentgrid.Rows.Count - 1; i++) { parentgrid[i, parentrange.Column] = false; } } } 复制代码
下面,需要处理单元格中所有CheckBox的选择/不选择操作。通过重写CreateCellContent方法可以处理单元格中CheckBox的选中/不选中状态,并依赖于这些状态来修改列头中CheckBox的状态,代码如下:
//实现单元格中的CheckBox功能 public override void CreateCellContent(C1.Silverlight.FlexGrid.C1FlexGrid grid, Border bdr, C1.Silverlight.FlexGrid.CellRange range) { base.CreateCellContent(grid, bdr, range); if (bdr.Child.GetType() == typeof(CheckBox)) { CheckBox childCkBox = bdr.Child as CheckBox; childCkBox.Checked += new RoutedEventHandler(childCkBox_Checked); childCkBox.Unchecked += new RoutedEventHandler(childCkBox_Unchecked); } } // 如果该类所有单元格中CheckBox都是选中状态,就将列头中的CheckBox设置为选中状态 void childCkBox_Checked(object sender, RoutedEventArgs e) { bool chkflag = true; for (int i = 0; i < parentgrid.Rows.Count; i++) { if ((bool)parentgrid[i, parentrange.Column] == false) { chkflag = false; break; } } if (chkflag) chk.IsChecked = true; } // 如果该类所有单元格中CheckBox都是未选中状态,就将列头中的CheckBox设置为未选中状态 void childCkBox_Unchecked(object sender, RoutedEventArgs e) { chk.IsChecked = false; } 复制代码
最终效果:
附上源码:VS2010 + ComponentOne for Silverlight 2011V3
- SL_Flexgrid_HeaderCellCheck.zip (358.46 K, 下载次数:48)