在项目中遇到的一个实际问题。现在有一个DataTable,希望能够自动显示在DataGrid中,但是因为有一个外键的关系,所以希望用ComboBox在定制某一列。xaml的方式比较死板,所以想用代码进行解析。直接上代码,稍后逐步解释。
1. DataGrid 初始化时分配数据(相应Initialized事件)
// 在这里第一次加载数据 DataTable dt = new DataTable("test"); // first of all, manually create a DataTable dt.Columns.Add(new DataColumn("id", typeof(int))); dt.Columns.Add(new DataColumn("name", typeof(string))); dt.Columns.Add(new DataColumn("测试", typeof(string))); // insert lines DataRow dr = dt.NewRow(); dr["id"] = 1; dr["name"] = "BB1"; dr["测试"] = "测试1"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["id"] = 2; dr["name"] = "BB2"; dr["测试"] = "测试2"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["id"] = 3; dr["name"] = "BB3"; dr["测试"] = "测试3"; dt.Rows.Add(dr); dataGrid.DataContext = dt;
2. 在WPF框架自动生成某个列的时候,进行干涉(响应AutoGeneratingColumn事件)
private void OnDataGridAutoGeneratingColumn( object sender, DataGridAutoGeneratingColumnEventArgs e) { // 只想干涉“id”列 if (e.PropertyName == "id") { // 模拟出外键所在的表 DataTable dt = new DataTable("test"); // first of all, manually create a DataTable dt.Columns.Add(new DataColumn("id", typeof(int))); dt.Columns.Add(new DataColumn("name", typeof(string))); // insert lines DataRow dr = dt.NewRow(); dr["id"] = 5; dr["name"] = "CC1"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["id"] = 6; dr["name"] = "CC2"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["id"] = 7; dr["name"] = "CC3"; dt.Rows.Add(dr); // 方法一:使用DataGridTemplateColumn定制ComboBox,有点是不编辑时,也是显示为ConboBox的样子 DataGridTemplateColumn column = new DataGridTemplateColumn(); column.Header = "id"; DataTemplate datatemplate = new DataTemplate(); FrameworkElementFactory fef = new FrameworkElementFactory(typeof(ComboBox)); Binding binding = new Binding(); binding.Source = dt.DefaultView; fef.SetBinding(ComboBox.ItemsSourceProperty, binding); Binding selectVal = new Binding("id"); selectVal.Mode = BindingMode.TwoWay; fef.SetBinding(ComboBox.SelectedValueProperty, selectVal); fef.SetValue(ComboBox.DisplayMemberPathProperty, "name"); fef.SetValue(ComboBox.SelectedValuePathProperty, "id"); datatemplate.VisualTree = fef; column.CellTemplate = datatemplate; e.Column = column; //方法二:使用DataGridConboBoxColumn,功能与上面的等价 //DataGridComboBoxColumn comboBoxColumn = new DataGridComboBoxColumn(); //comboBoxColumn.Header = "fuck"; //// ComboBox 选择后的值 //comboBoxColumn.SelectedValuePath = "id"; //// ComboBox 前台显示的值 //comboBoxColumn.DisplayMemberPath = "name"; //Binding binding = new Binding(); //// 需要绑定的列 //binding.Path = new PropertyPath("id");
//指定立即更新
//binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; //comboBoxColumn.SelectedValueBinding = binding; //Binding itemsSourceBinding = new Binding(); //itemsSourceBinding.Source = dt.DefaultView; //BindingOperations.SetBinding(comboBoxColumn, DataGridComboBoxColumn.ItemsSourceProperty, itemsSourceBinding); //e.Column = comboBoxColumn; } }
关于ComboBox的各个Property的意思,请参看http://blogs.msdn.com/b/vinsibal/archive/2008/10/31/wpf-datagrid-datagridcomboboxcolumn-v1-intro.aspx , 里面有一个关于外键的例子。
关于DataGridTemplateColumn 的使用,主要参考了http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/3ada4685-a032-4bf0-9514-f86c44967678?persist=True ,但是也有一点修改,主要是,一个Panel加进去之后就不工作了。。。