在C1FlexGrid for Silverlight的列头中添加CheckBox功能

发布时间:2012/11/15 00:11 发布者:葡萄城产品团队

返回博客中心

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

关于葡萄城

赋能开发者!葡萄城是专业的集开发工具、商业智能解决方案、低代码开发平台于一身的软件和服务提供商,为超过 75% 的全球财富 500 强企业提供服务。葡萄城专注控件软件领域30年,希望通过模块化的开发控件、灵活的低代码应用开发平台等一系列开发工具、解决方案和服务,帮助开发者快速响应复杂多变的业务需求,最大程度地发挥开发者的才智和潜能,让开发者的 IT 人生更从容更美好。

了解详情,请访问葡萄城官网