Silverlight学习笔记三:如何自定义DataGrid的Header
2008-12-29 14:12
621 查看
接上篇,继续学习DataGrid。下面我来学习DataGrid的Header的自定义功能。
在上篇中,我们实现的对Grid的排序,但是用的是Grid自动生产的Header,现在我们用自定义的控件来代替系统自动生成的Header,并且在Header下面添加一个可以对数据进行过滤的功能。
在这里我参考了silverlight.net上一群牛人的代码。
因为过去没有用过silverlight,在silverlight.net上听说在2.0RC出来之前,自定义ColumnHeader很容易,只需要设置Column.Header为某个控件就可以了,但是现在全变了,Column.Header变成了表头的内容了,要更改Header,必须用做一个新的Style,赋给Column.HeaderStyle。不是太明白微软问什么要这样做,把一个简单的问题搞的很复杂,对一个新手来说,做一个Style真的很费事。按照字面的意思,我认为Style应该是用来控制控件的展现方式,有点像 WEB 上的 CSS ,但是这里的Style不但可以控制如何展示控件,还要设置用什么控件,如何绑定数据,甚至还是事件的处理等等,感觉像个像个自定义控件,但是又没有自定义控件好用。
好了,废话不说了,先看效果:
<!--DataGrid-->
<data:DataGrid x:Name="dgData" AutoGenerateColumns="False"
SelectionMode="Single" IsReadOnly="True"
Grid.Column="0" Grid.Row="2"
Height="Auto" Width="Auto" CanUserSortColumns="False"
CanUserReorderColumns="False"
MouseEnter="dgData_MouseEnter" MouseLeave="dgData_MouseLeave"
>
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="产品编号" Binding="{Binding ProductID}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="产品名称" Binding="{Binding ProductName}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="单价" Binding="{Binding UnitPrice}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="库存数量" Binding="{Binding UnitsInStock}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="订单数量" Binding="{Binding UnitsOnOrder}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="规格" Binding="{Binding QuantityPerUnit}"></data:DataGridTextColumn>
<data:DataGridCheckBoxColumn Header="是否停产" Binding="{Binding Discontinued}"></data:DataGridCheckBoxColumn>
<data:DataGridTemplateColumn Header="操作">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button x:Name="btnEdit" Content="编辑" ></Button>
<Button x:Name="btnDelete" Content="删除"></Button>
</StackPanel>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
在获取数据之后,对DataGrid的Header进行了处理。新增了CreateHeader()这个方法。
1 private void client_GetProductsPagingCompleted(object sender, GetProductsPagingCompletedEventArgs e)
2 {
3 if (e.Error == null)
4 {
5 products_list = e.Result.ToList();
6 dgData.ItemsSource = products_list;
7 if (pager == null)
8 {
9 pager = new Pager(e.TotalPage, 2);
pager.Click += new Pager.PagerButtonClick(pager_Click);
pager.PageIndex = 1;
spPager.Children.Clear();
spPager.Children.Add(pager);
//第一次时创建GridHeader
CreateHeader();
}
}
else
MessageBox.Show(e.Error.Message);
canvas.Visibility = Visibility.Collapsed;
}
//用来存储HeaderText和数据库字段之间的对照信息
Dictionary<string, string> FieldDict = new Dictionary<string, string>();
private void CreateHeader()
{
var v = from p in dgData.Columns
where p is DataGridBoundColumn
select p;
foreach (DataGridBoundColumn column in v.ToList())
{
string fieldname = column.Binding.Path.Path;
Style style_header = Resources["grid-header"] as Style;
column.HeaderStyle = style_header;
//本来这里我是希望可以直接设置Header的FieldText为字段名的,但是却找不到什么好的方法,
//
//<my:GridHeader HeaderText="{TemplateBinding Content}" Height="Auto" Loaded="GridHeader_Loaded" />
//Resources中这里也不能直接绑定FieldText为Binding.Path.Path,因为这里是从DataGridColumnHeader来的,
//DataGridColumnHeader只有Content,而找不到对应的绑定信息。
//
//另外,通过访问Style的Setter,我也只能获取到ControlTemplate,但是ControlTemplate下面的内容,也就是my:GridHeader取怎么也获取不到,
//如果有高人知道,请指教一下。谢谢
//
//所以,没办法,只能暂时把字段名和HeaderText都保存到Dictionary里面,供后面使用
FieldDict.Add(column.Header.ToString(), fieldname);
}
}
private void GridHeader_Loaded(object sender, RoutedEventArgs e)
{
GridHeader header = sender as GridHeader;
header.OnFilter += new GridHeader.FilterTextEvent(header_OnFilter);
header.OnSort += new GridHeader.HeaderClickEvent(header_OnSort);
string fieldtext;
//在这里,我们对Header的FieldText设置为字段名。
//如果能在这里获取到当前的Column的话,前面就不要用Dictionary了,但是这里我仍然不知道该怎么获取到当前的Column。
if (FieldDict.TryGetValue(header.HeaderText, out fieldtext))
header.FieldText = fieldtext;
}
void header_OnSort(string fieldname)
{
//这里具体的代码就不写了。
//在获取到字段名之后,对数据进行排序。
MessageBox.Show("对字段:" + fieldname + "进行排序");
}
void header_OnFilter(string fieldname, string filtertext)
{
//这里具体的代码就不写了。
//在获取到字段名和关键字只有,就可以通过WCF获取到指定的数据了。
MessageBox.Show("对字段:" + fieldname + " 按照 " + filtertext + " 进行过滤");
}
ok,打完手工。
在上篇中,我们实现的对Grid的排序,但是用的是Grid自动生产的Header,现在我们用自定义的控件来代替系统自动生成的Header,并且在Header下面添加一个可以对数据进行过滤的功能。
在这里我参考了silverlight.net上一群牛人的代码。
因为过去没有用过silverlight,在silverlight.net上听说在2.0RC出来之前,自定义ColumnHeader很容易,只需要设置Column.Header为某个控件就可以了,但是现在全变了,Column.Header变成了表头的内容了,要更改Header,必须用做一个新的Style,赋给Column.HeaderStyle。不是太明白微软问什么要这样做,把一个简单的问题搞的很复杂,对一个新手来说,做一个Style真的很费事。按照字面的意思,我认为Style应该是用来控制控件的展现方式,有点像 WEB 上的 CSS ,但是这里的Style不但可以控制如何展示控件,还要设置用什么控件,如何绑定数据,甚至还是事件的处理等等,感觉像个像个自定义控件,但是又没有自定义控件好用。
好了,废话不说了,先看效果:
<!--DataGrid-->
<data:DataGrid x:Name="dgData" AutoGenerateColumns="False"
SelectionMode="Single" IsReadOnly="True"
Grid.Column="0" Grid.Row="2"
Height="Auto" Width="Auto" CanUserSortColumns="False"
CanUserReorderColumns="False"
MouseEnter="dgData_MouseEnter" MouseLeave="dgData_MouseLeave"
>
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="产品编号" Binding="{Binding ProductID}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="产品名称" Binding="{Binding ProductName}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="单价" Binding="{Binding UnitPrice}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="库存数量" Binding="{Binding UnitsInStock}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="订单数量" Binding="{Binding UnitsOnOrder}"></data:DataGridTextColumn>
<data:DataGridTextColumn Header="规格" Binding="{Binding QuantityPerUnit}"></data:DataGridTextColumn>
<data:DataGridCheckBoxColumn Header="是否停产" Binding="{Binding Discontinued}"></data:DataGridCheckBoxColumn>
<data:DataGridTemplateColumn Header="操作">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button x:Name="btnEdit" Content="编辑" ></Button>
<Button x:Name="btnDelete" Content="删除"></Button>
</StackPanel>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
在获取数据之后,对DataGrid的Header进行了处理。新增了CreateHeader()这个方法。
1 private void client_GetProductsPagingCompleted(object sender, GetProductsPagingCompletedEventArgs e)
2 {
3 if (e.Error == null)
4 {
5 products_list = e.Result.ToList();
6 dgData.ItemsSource = products_list;
7 if (pager == null)
8 {
9 pager = new Pager(e.TotalPage, 2);
pager.Click += new Pager.PagerButtonClick(pager_Click);
pager.PageIndex = 1;
spPager.Children.Clear();
spPager.Children.Add(pager);
//第一次时创建GridHeader
CreateHeader();
}
}
else
MessageBox.Show(e.Error.Message);
canvas.Visibility = Visibility.Collapsed;
}
//用来存储HeaderText和数据库字段之间的对照信息
Dictionary<string, string> FieldDict = new Dictionary<string, string>();
private void CreateHeader()
{
var v = from p in dgData.Columns
where p is DataGridBoundColumn
select p;
foreach (DataGridBoundColumn column in v.ToList())
{
string fieldname = column.Binding.Path.Path;
Style style_header = Resources["grid-header"] as Style;
column.HeaderStyle = style_header;
//本来这里我是希望可以直接设置Header的FieldText为字段名的,但是却找不到什么好的方法,
//
//<my:GridHeader HeaderText="{TemplateBinding Content}" Height="Auto" Loaded="GridHeader_Loaded" />
//Resources中这里也不能直接绑定FieldText为Binding.Path.Path,因为这里是从DataGridColumnHeader来的,
//DataGridColumnHeader只有Content,而找不到对应的绑定信息。
//
//另外,通过访问Style的Setter,我也只能获取到ControlTemplate,但是ControlTemplate下面的内容,也就是my:GridHeader取怎么也获取不到,
//如果有高人知道,请指教一下。谢谢
//
//所以,没办法,只能暂时把字段名和HeaderText都保存到Dictionary里面,供后面使用
FieldDict.Add(column.Header.ToString(), fieldname);
}
}
private void GridHeader_Loaded(object sender, RoutedEventArgs e)
{
GridHeader header = sender as GridHeader;
header.OnFilter += new GridHeader.FilterTextEvent(header_OnFilter);
header.OnSort += new GridHeader.HeaderClickEvent(header_OnSort);
string fieldtext;
//在这里,我们对Header的FieldText设置为字段名。
//如果能在这里获取到当前的Column的话,前面就不要用Dictionary了,但是这里我仍然不知道该怎么获取到当前的Column。
if (FieldDict.TryGetValue(header.HeaderText, out fieldtext))
header.FieldText = fieldtext;
}
void header_OnSort(string fieldname)
{
//这里具体的代码就不写了。
//在获取到字段名之后,对数据进行排序。
MessageBox.Show("对字段:" + fieldname + "进行排序");
}
void header_OnFilter(string fieldname, string filtertext)
{
//这里具体的代码就不写了。
//在获取到字段名和关键字只有,就可以通过WCF获取到指定的数据了。
MessageBox.Show("对字段:" + fieldname + " 按照 " + filtertext + " 进行过滤");
}
ok,打完手工。
相关文章推荐
- 强大的DataGrid组件[9]_自定义头模板(HeaderTemplate)——Silverlight学习笔记[17]
- 强大的DataGrid组件[9]_自定义头模板(HeaderTemplate)——Silverlight学习笔记[17]
- Silverlight学习笔记四:如何通过自定义ComboBox实现SelectedValue
- 强大的DataGrid组件[7]_自定义DataGrid——Silverlight学习笔记[15]
- SilverLight学习笔记--Silverligh之如何显示用户自定义的 Splash Screen (初始屏幕)
- Silverlight学习笔记一:DataGrid如何处理鼠标的滚轮事件
- 强大的DataGrid组件[7]_自定义DataGrid——Silverlight学习笔记[15]
- 强大的DataGrid组件[10]_自定义脚模板(FooterTemplate)——Silverlight学习笔记[18]
- php学习笔记_Smarty变量调节器以及如何自定义
- Silverlight学习笔记二:DataGrid 服务器端分页、排序的实现
- [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器
- Silverlight学习笔记[6] - 如何:定义 Windows Communication Foundation 服务协定
- 强大的DataGrid组件[2]_数据交互之ADO.NET Entity Framework——Silverlight学习笔记[10]
- 强大的DataGrid组件[5]_实现CURD[下]——Silverlight学习笔记[13]
- 强大的DataGrid组件[11]_主从(Master-Details)的实现——Silverlight学习笔记[19]
- 强大的DataGrid组件[14][Final]_数据验证——Silverlight学习笔记[22]
- django学习笔记---如何自定义中间件详解
- Silverlight学习笔记三:表格控件DataGrid
- SilverLight学习笔记--如何在xaml文件中操作用户在后台代码定义的类(2)--示例篇:创建一个登录控件(原创)(转载本文请注明出处)
- 强大的DataGrid组件[3]_数据交互之Linq to SQL——Silverlight学习笔记