在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
|