在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家合作伙伴紧密合作,产品广泛应用于信息和软件服务、制造、交通运输、建筑、金融、能源、教育、公共管理等支柱产业。
葡萄城热门产品


