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

在WinForms和WebForms程序中,我们使用表格控件时经常会有这样的需求:如果这一列的单元格时CheckBox类型,我们希望在列头也添加一个CheckBox,通过对列头CheckBox的操作来完成对该列所有CheckBox的选中/不选中操作。下面我们就来看一看在C1FlexGrid for Silverlight中如何实现这一功能。

发布于 2012/11/15 00:00

ComponentOne Enterprise

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

关于葡萄城

葡萄城是专业的软件开发技术和低代码平台提供商,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。葡萄城开发技术始于1980年,40余年来始终聚焦软件开发技术,有深厚的技术积累和丰富的产品线。是业界能够同时赋能软件开发和低代码开发的企业。凭借过硬的产品能力、活跃的用户社区和丰富的伙伴生态,与超过3000家合作伙伴紧密合作,产品广泛应用于信息和软件服务、制造、交通运输、建筑、金融、能源、教育、公共管理等支柱产业。

相关产品
推荐相关案例
关注微信
葡萄城社区二维码

关注“葡萄城社区”

加微信获取技术资讯

加微信获取技术资讯

想了解更多信息,请联系我们, 随时掌握技术资源和产品动态