列名包含"."的DataTable,如何binding到DataGrid上?

这个问题是今天的工作中遇到的,不过却不是我解决,记录在这里,一是给自己备个份,二是可以和大家交流一下,也许还有更好的方法。

首先,建立一个WPF应用程序,FrameWork要4.0的,然后在Window里面添加一个DataGrid控件,Xaml如下:

<Window x:Class="BindingWithPeriod.MainWindow"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
Title
="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="dgDisplay" CanUserAddRows="False">

</DataGrid>
</Grid>
</Window>

接着,再新建一个ViewModel类,里面只有一个DataTable的属性,这个DataTable里面有列名包含点,比如"Number.A",具体代码如下:

using System;
using System.Data;

namespace BindingWithPeriod
{
public class TestViewModel
{
public TestViewModel()
{
CurrentDataTable
= new DataTable();
CurrentDataTable.Columns.Add(
new DataColumn("ID", typeof(string)));
CurrentDataTable.Columns.Add(
new DataColumn("Number.A", typeof(int)));
Random random
= new Random();
for (int i = 1; i <= 100; i++)
{
DataRow row
= CurrentDataTable.NewRow();
row[
0] = i.ToString();
row[
1] = random.Next(-10000, 10000);
CurrentDataTable.Rows.Add(row);
}
}

public DataTable CurrentDataTable { get; set; }
}
}

  

最后就Binding吧,然后F5,程序就报错了,异常信息如下(通过Snoop得到的):

System.Windows.Data Error: 40 : BindingExpression path error: 'Number' property not found
on 'object' ''DataRowView' (HashCode=60213203)'. BindingExpression:Path=Number.A;
DataItem='DataRowView' (HashCode=60213203);
target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

这里,重点就来了,相信大家看到这个异常也知道原因了,Path的内容是Number.A,意思指向就是Number的A属性,但实际上Number.A是一个列名,并不存在Number属性和A属性。

后来在强大的leader的帮助下,找到了解决方案,首先,给DataGrid加AutoGeneratingColumn事件,事件里面添加如下代码:

//if the column contains period, give it a new binding.
if (e.PropertyName.Contains("."))
{
string path=string.Format("[{0}]", e.PropertyName);
((DataGridBoundColumn)e.Column).Binding
= new Binding(path);
}

这样,程序就可以跑起来了,不过当你点击列Number.A,它并不会自动排序了,所以我们还需要添加一个Sorting事件来处理Number.A的排序,代码如下:

string columnName = e.Column.Header.ToString();
//if the column contains period, remove '[' and ']' and let DataView sort 
automatically.
if (columnName.Contains("."))
{
e.Column.SortMemberPath
= columnName.Trim(new char[] { '[', ']' });
}

完整代码下载

posted @ 2011-07-29 21:48  Little Prince  阅读(618)  评论(0编辑  收藏  举报