Silverlight中DataGrid用法解析
DataGrid模版列简介
DataGrid在Silverlight中是一个重要的数据控件,可以分组显示,可以排序,自定义模版,极大的方便了我们对数据集的操作和展示。通常为了添加模版列,我们需要将DataGrid的AutoGenerateColumns属性设为false
DataGrid中对于添加的列类型有三种:
DataGridTemplateColumn (自定义模板列) ----可以添加任何控件,比如Image,button 等等
DataGridTextColumn (文本列)-----只需对其进行简单的数据绑定
DataGridCheckBoxColumn (选择列)----只需对其进行简单的数据绑定即可
自定义模版头
我们知道Silverlight自带的模版头样式不能够放入CheckBox,testbox等控件,即便是DataGridCheckBoxColumn选择列也只能在数据行中才能显示CheckBox框但实际项目中,我们常常遇到这样的问题,例如我们要全选某一列,那么我们就需要在模版头上有一个CheckBox.,这里我们可以修改模版头的样式来实现。代码如下:
<sdk:DataGridCheckBoxColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False" Width="*" Binding="{Binding isTaxed}" >
<sdk:DataGridCheckBoxColumn.HeaderStyle>
<Style TargetType="Primitives:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel >
<CheckBox Content="全选" Name="chkAll"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGridCheckBoxColumn.HeaderStyle>
</sdk:DataGridCheckBoxColumn>
注意:要使用此样式,需要加入一以下命名空间支持:
xmlns:Primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
效果如下:
自定义模版列
DataGrid的单元格的状态有两种,即编辑状态和非编辑状态,在实际开发中,如果一个单元格所在的列不设为只读的话(即可读可写),那么这个单元格就存在此两种状态。此时则应按需分别设定不同的编辑模版。如下:
非编辑状态模版:<sdk:DataGridTemplateColumn.CellTemplate>
编辑状态模版: <sdk:DataGridTemplateColumn.CellEditingTemplate>
下面以一个示例来完成介绍
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="编号" IsReadOnly="True"
Binding="{Binding EmployeeID,Mode=OneWay}" /><!--该列只读-->
<sdk:DataGridTextColumn Header="名称"
Binding="{Binding EmployeeName,Mode=TwoWay}" />
<sdk:DataGridTextColumn Header="年龄"
Binding="{Binding EmployeeAge,Mode=TwoWay}" />
<sdk:DataGridTemplateColumn Header="性别" Width="80">
<sdk:DataGridTemplateColumn.CellTemplate><!--普通显示模式-->
<DataTemplate>
<TextBlock Text="{Binding EmployeeSex}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate><!--编辑模式-->
<DataTemplate>
<ComboBox Width="80" ItemsSource="{Binding cbSexList,
Source={StaticResource cbSexListProvider}}”
SelectedItem="{Binding EmployeeSex,Mode=TwoWay}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridCheckBoxColumn Header="是否税后" Binding="{BindingEmployeeMarried,Mode=TwoWay}" />
</ sdk:DataGrid.Columns>
</sdk:DataGrid>
DataGrid实现对绑定数据的增,删,改
难点解析
一.采用集中绑定,而非单列绑定,导致页面数据在修改后无法实时更新问题
我们知道,在使用WCF服务时,我们一般的返回值均为一个列表,而在前台页面的后台代码中,我们知识简单的将列表的值绑定到DataGrid中,来完成数据的显示,但这种后果就是,我们在修改或删除操作时,无法实时更新页面的显示数据,必须采用“F5”强制刷新页面来解决,这显然不符合要求,这里我们提供一种方法,仅供大家参考
二.解决方法思路:
在修改某一行的数据时,我们将此行的数据捕获,并读入一个类中保存,当然,DataGrid还可以将数据直接保存到一个Table行中,同样奏效,然后将数据显示在子窗体中,并在子窗体中完成修改,这样我们在主窗体代码中注册一下子窗体的Closed事件,并在该事件中重新绑定数据源(注意,子窗体的Closed事件实在父窗体中定义而非子窗体自身),这样我们在利用子窗体完成增加或修改操作后,均可重新绑定数据源来完成页面刷新的效果。方法中涉及到子窗体和父窗体的交互传值问题。
修改操作:子窗体中可以如下定义
private MainPage main;其中main即为主窗体的实例对象,当然要使此对象完成和主窗体的交互功能,还需修改子窗体的构造函数,如下:
public ChildWindow(MainPage main)
{
InitializeComponent();
this.main=main;//完成子窗体和父窗体的联系。
}
当然主窗体在定义子窗体实例时,得如下定义了:
ChildWindow child=new ChildWindow(this);//这样就达到了子父窗体的交互问题了。
private void OKButton_Click(object sender, RoutedEventArgs e)
{
//其中t为父窗体中定义的一个Table实例对象,
Service1Client sc = new Service1Client();
main.t.产品名称 = textBoxName.Text;
main.t.产品类型 = textBoxType.Text;
main.t.卫星类型 = textBoxSaType.Text;
main.t.行业示范类型 = textBoxjobType.Text;
main.t.产品算法名称 = textBoxAcmName.Text;
main.t.生产时间 = textBoxTime.Text;
sc.UpdateAsync(main.t);
sc.UpdateCompleted+=new EventHandler<UpdateCompletedEventArgs>(sc_UpdateCompleted);
this.DialogResult = true;
}
父窗体中还需注册子窗体的Closed事件,来完成页面的刷新功能。
ChildWindow Child;//子窗体的对象
public MainPage()
{
InitializeComponent();
DataBind();//绑定数据源函数
Child.Closed += new EventHandler(Child_Closed);
}
void Child_Closed(object sender, EventArgs e)
{
if (d.DialogResult == true)
{
DataBind();
}
}
至于添加和删除操作,相对来说比较简单,这里就不在赘述。
DataGrid分页、排序和分组功能实现
实现方法简介:
若要实现分页及排序功能,就必须使用PagedCollectionView这个类,其功能是用来表示分组,排序,筛选,和导航分页数据集合的视图。关于此类的详细介绍,请参考:
分页功能实现
当页面进行大量数据展示时,往往需要分页效果,Silverlight4.0和5.0都提供了DataPager控件,这样我们很方便就可以实现DataGrid的分页效果。
注意事项:
当我们是直接从工具箱中拖放DataPager控件而非收到编写XAML文件时,系统默认每页展示的个数为10,如果我们在XAML文件中不做修改,即便在后台定义DataPager的PageSize属性为4,界面显示的行数仍然为10,因为XAML属性在编译时的优先级高。
这里我们使用一个集合类来充当数据源,来解释分页功能的实现
获得数据源
public List<EmployeeInfo> GetEmployeeList()
{
List<EmployeeInfo> employeeList = new List<EmployeeInfo>();
EmployeeInfo[] test = new EmployeeInfo[12];
test[0] = new EmployeeInfo(1, "张三", 1000,"开封" ,"Images/1.jpg",true);
test[1] = new EmployeeInfo(2, "张四", 2000, "开封","Images/3.jpg",true);
test[2] = new EmployeeInfo(3, "张五", 3000, "开封","Images/4.jpg",false);
test[3] = new EmployeeInfo(4, "张六", 4000, "开封","Images/5.jpg",true);
test[4] = new EmployeeInfo(5, "张七", 5000, "开封","Images/7.jpg",false);
test[5] = new EmployeeInfo(6, "张八", 6000, "开封","Images/8.jpg",true);
test[6] = new EmployeeInfo(7, "张九", 7000, "开封","Images/10.jpg",false);
test[7] = new EmployeeInfo(8, "张十", 8000, "开封","Images/11.jpg",true);
test[8] = new EmployeeInfo(9, "李四", 9000, "开封","Images/12.jpg",false);
test[9] = new EmployeeInfo(10, "李五", 10000, "开封","Images/13.jpg",true);
test[10]=newEmployeeInfo(11, "李五", 11000, "开封","Images/14.jpg",false);
test[10]=new EmployeeInfo(12, "李六", 12000, "开封","Images/15.jpg",true);
employeeList.AddRange(test);
return employeeList;
}
绑定数据实现分页
public MainPage()
{
InitializeComponent();
PagedCollectionView pcv = new PagedCollectionView(GetEmployeeList());
dataPagerdemo01.Source = pcv;//设置DataPager数据源
dataGrid1.ItemsSource = pcv;//设置DataGrid数据源
}
同时,如果我们是直接从工具箱中拖放控件,请修改XAML文件中的PageSize属性,例如<sdk:DataPager Source="{Binding}" PageSize="4" x:Name="dataPagerdemo01"………/>
最后效果如下:
排序功能实现
实现方法简介:
主要使用了PagedCollectionView类的SortDescriptions属性来控制视图选项,基本思路是选择集合中的某个属性作为参照,再设置排序的方式,最终这种设置会被一个SortDescription对象捕获,若同时对多个属性进行排序,按照添加至SortDescriptions的顺序表示优先级。
排序功能实现:
pcv.SortDescriptions.Add
(new SortDescription("Salary",ListSortDirection.Descending));
pcv.SortDescriptions.Add
(new SortDescription("EmployeeID",ListSortDirection.Ascending));
dataPagerdemo01.Source = pcv;
dataGrid1.ItemsSource = pcv;
这样,集合会根据Salary属性进行降序排列,如果Salary属性相同,则根据EmployeeID属性进行升序排列。效果如下:
如果想返回默认排序,实际上及返回源数据集合项,则可使用pcv.SortDescriptions.Clear();来完成。
分组功能实现
实现方法简介:
主要使用了GroupDescriptions这一属性,它与上面所讲的SortDescriptions很类似,其可以添加PropertyGroupDescription对象,把源集合进行分组
分组功能实现
pcv.GroupDescriptions.Add(new PropertyGroupDescription(“isTaxed”));
效果如下:
其中,分组是根据isTaxed的值来区分的,其值有Fasle和True两项,但通常,我们显示的分组表头为汉字,那么我们可以新建一个属性转换类来实现此类效果。
在public partial class Mainpage:UserControl类中,加入一个转换类:
public class BoolValueConvertrt : IValueConverter
{
public object Convert(object value, Type targetType, object parameter , System.Globalization.CultureInfo culture)
{
return (bool)value ? "税后" : "非税后";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
再修改分组语句如下:
pcv.GroupDescriptions.Add(new PropertyGroupDescription("isTaxed",new BoolValueConvertrt()));,最后的效果如下:
作者:yidifanhua
出处:http://www.cnblogs.com/yidifanhua/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。