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"

效果如下:

image

自定义模版列

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这个类,其功能是用来表示分组,排序,筛选,和导航分页数据集合的视图。关于此类的详细介绍,请参考:

http://msdn.microsoft.com/zh-cn/library/system.windows.data.pagedcollectionview_members(v=vs.95).aspx

分页功能实现

当页面进行大量数据展示时,往往需要分页效果,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"………/>

最后效果如下:

image

排序功能实现

实现方法简介:

主要使用了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属性进行升序排列。效果如下:

image

如果想返回默认排序,实际上及返回源数据集合项,则可使用pcv.SortDescriptions.Clear();来完成。

分组功能实现

实现方法简介:

主要使用了GroupDescriptions这一属性,它与上面所讲的SortDescriptions很类似,其可以添加PropertyGroupDescription对象,把源集合进行分组

分组功能实现

pcv.GroupDescriptions.Add(new PropertyGroupDescription(“isTaxed”));

效果如下:

image

其中,分组是根据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()));,最后的效果如下:

image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章