首页 | 新闻 | 交流 | 问吧 | 文档 | 手册 | 下载 | 博客

SilverLight之路(六)

作者:  时间: 2011-06-15

结束了一个模块的练习,是不是对Silverlight的结构与使用有了一定的了解了呢?不过毕竟“风险测试”这个模块的功能还是太简单了,那接下来我们开始第二个模块的练习吧,进入“客户管理”模块,主要应用DataGrid、DataPager控件,这节主要说一下全选功能的实现。

先看下效果(比较懒了,样式就没再细调,只注重功能的实现了)

 

模块主体主要就是一个DataGrid与DataPager的结合,在布局方面有一个注意的地方,在最外层我使用了一个Border控件,它有一个CornerRadius属性用来设置Border的圆角弧度,注意它的类型,虽然它可以接收一个数字为参数,但不要以为它就只可以设置四个角为一样的弧度,你也可以这样进行设置

 

就如我们的效果一样,设置左上与右上两个角为圆弧,左下与右下保持直角不变。

先看下DataGrid与DataPager的简单实现

<sdk:DataGrid x:Name="dgCustomerList" ></sdk:DataGrid>
<sdk:DataPager x:Name="dpCustomerList" PageSize="20" DisplayMode="FirstLastNumeric"/>

后台代码

client.GetCustomerListPagerCompleted += new EventHandler<WcfService.GetCustomerListPagerCompletedEventArgs>(
(s, ex)
=>
{
PagedCollectionView pcv
= new PagedCollectionView(ex.Result);
this.dgCustomerList.ItemsSource = pcv;
this.dpCustomerList .Source = pcv;
});

没了,就这么简单,MS已经把绑定与分页做到极致傻瓜式了。但往往我们的项目中,这种太过简单的实现是满足不了要求的,就比如一般的数据源中都会有ID标识列,我们这样利用自动生成列的办法显然不行,那我们就麻烦点,手动创建列吧。

<sdk:DataGrid x:Name="dgCustomerList" AutoGenerateColumns="False" >
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="客户姓名" Binding="{Binding 客户姓名}"/>
<sdk:DataGridTextColumn Header="证件号码" Binding="{Binding 证件号码}"/>
<sdk:DataGridTextColumn Header="客户类型" Binding="{Binding 客户类别}"/>
<!—模板列-->
<sdk:DataGridTemplateColumn Header="账户分析">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<HyperlinkButton Content="查看" Tag="{Binding FundAccount}" HorizontalAlignment="Center" VerticalAlignment="Center"></HyperlinkButton>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<!--其它列-->
</sdk:DataGrid.Columns>
</sdk:DataGrid>

这里,如果你有某一列没有指定数据源,例如没有设置Binding,则打开页面时就会出问题,我这里就是白屏了。

一般我们的数据表格会在第一列有一个选择列的存在,以方便对某些行进行选择,我们也是使用模块列来实现(虽然DataGrid自己提供了一个DataGridCheckBoxColumn,但也要绑定数据源,而我们的源数据里是没有一个bool字段用来给它绑定的,因此我觉得用起来比较不方便,就用了模板列)

<sdk:DataGridTemplateColumn HeaderStyle="{StaticResource DataGridColumnHeaderStyle1}" CellTemplate="{StaticResource DataTemplate1}"/>

用列头模块加载一个用来进行全选的CheckBox,单元格模板加载一个CheckBox,资源。。。代码太多了,我就不贴了,都是Blend自动生成的,我只贴关键部分吧

列头模板

 

<CheckBox x:Name="ckHeader" Content="" Click="CheckBox_Click" HorizontalAlignment="Center" VerticalAlignment="Center"/>

单元格模板 

<DataTemplate x:Key="DataTemplate1">
<CheckBox x:Name="ck" Content="" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DataTemplate>

后台代码

 

View Code
//记录选择行
private ObservableCollection< WcfService.WFT_Batch_CustomerClassification> selectItem = new ObservableCollection< WcfService.WFT_Batch_CustomerClassification>();

private void CheckBox_Click(object sender, System.Windows.RoutedEventArgs e)
{
//全选
CheckBox chk = sender as CheckBox;
ckHeader
= chk;//记录列头全选按钮引用
bool check = chk.IsChecked.Value;
PagedCollectionView pcv
= this.dgCustomerList.ItemsSource as PagedCollectionView;//注意,这里为当前页

if (check)
{
foreach (WcfService.WFT_Batch_CustomerClassification p in pcv)
{
selectItem.Add(p);
chk
= this.dgCustomerList.Columns[0].GetCellContent(p) as CheckBox;
if (chk != null)
chk.IsChecked
= true;
}
}
else
{
foreach (WcfService.WFT_Batch_CustomerClassification p in pcv)
{
chk
= this.dgCustomerList.Columns[0].GetCellContent(p) as CheckBox;
if (chk != null)
chk.IsChecked
= false;
}
selectItem.Clear();
}
}

void dgCustomerList_LoadingRow(object sender, DataGridRowEventArgs e)
{
CheckBox chk
= (CheckBox)this.dgCustomerList.Columns[0].GetCellContent(e.Row);
chk.Click
+= new RoutedEventHandler(chk_Click);
WcfService.WFT_Batch_CustomerClassification p
= chk.DataContext as WcfService.WFT_Batch_CustomerClassification;
chk.IsChecked
= selectItem.Contains(p);
}

void chk_Click(object sender, RoutedEventArgs e)
{
CheckBox chk
= sender as CheckBox;
bool check = chk.IsChecked.Value;
WcfService.WFT_Batch_CustomerClassification p
= chk.DataContext as WcfService.WFT_Batch_CustomerClassification;

if (check)
{
if (!selectItem.Contains(p))
selectItem.Add(p);
}
else
{
selectItem.Remove(p);
}
}

传统的实现上,当进行分页后,要清掉选择数据

 

void dpCustomerList_PageIndexChanged(object sender, EventArgs e)
{
selectItem.Clear();
if (ckHeader != null)
ckHeader.IsChecked
= false;
}

 

这个方案里LoadingRow事件比较关键,否则你会发现很奇怪的问题,滚动条滚滚试试,勾选状态没了,呵呵。

另外,如果想锁列,只要设置一下DataGrid的FrozenColumnCount属性就可以了。