WPF DataGrid绑定支持动态增减列、行过滤的数据源及事件异常排查
WPF DataGrid动态列绑定与编辑触发异常问题
开发了一款可查看、修改源文件内容的应用,源文件包含两类核心数据集合:
- 图纸项:包含名称、ID等基础属性
- SheetSets分组集合:每个分组记录其所关联的图纸信息,同一张图纸可归属多个SheetSet
应用支持的核心操作包括:筛选需展示的图纸、新增SheetSet、为SheetSet分配关联图纸,所有操作产生的修改需同步回源文件,因此选用DataGrid实现交互界面。
目前在数据绑定环节遇到异常:从源文件拉取内容构建DataTable,再将DataGrid绑定到该DataTable的DataView,核心后台实现代码如下:
public static void UpdateDataGrid(UIApplication uiApp, Ui ui) { UIDocument uidoc = uiApp.ActiveUIDocument; var viewSheetSets = new FilteredElementCollector(uidoc.Document).OfClass(typeof(ViewSheetSet)).ToElements(); var viewSheets = new FilteredElementCollector(uidoc.Document).OfClass(typeof(ViewSheet)).ToElements(); DataTable dt = new DataTable(); DataColumn sheetNumberColumn = dt.Columns.Add("Sheet Number"); sheetNumberColumn.ReadOnly = true; DataColumn sheetNameColumn = dt.Columns.Add("Sheet Name"); sheetNameColumn.ReadOnly = true; DataColumn sheetIdColumn = dt.Columns.Add("Sheet Id", typeof(Int32)); sheetIdColumn.ReadOnly = true; foreach (ViewSheet viewSheet in viewSheets) { if (!viewSheet.IsPlaceholder) { DataRow row = dt.NewRow(); row["Sheet Number"] = viewSheet.SheetNumber; row["Sheet Name"] = viewSheet.Name; row["Sheet Id"] = viewSheet.Id.IntegerValue; foreach (ViewSheetSet ss in viewSheetSets) { if (!dt.Columns.Contains(ss.Name)) { DataColumn column = dt.Columns.Add(ss.Name, typeof(Boolean)); column.ReadOnly = false; } else if (ss.Views.Contains(viewSheet)) { row[ss.Name.ToString()] = true; } else { row[ss.Name.ToString()] = false; } } dt.Rows.Add(row); } } if (ui.LblFilterText.Text != "") { if (ui.conditionComboBox.Text == "CONTAINS") { EnumerableRowCollection<DataRow> query = from row in dt.AsEnumerable() where row.Field<string>("Sheet Name").ToLower().Contains(ui.LblFilterText.Text.ToLower()) select row; ui.uiDV = query.AsDataView(); } else if (ui.conditionComboBox.Text == "DOES NOT CONTAIN") { EnumerableRowCollection<DataRow> query = from row in dt.AsEnumerable() where !row.Field<string>("Sheet Name").ToLower().Contains(ui.LblFilterText.Text.ToLower()) select row; ui.uiDV = query.AsDataView(); } else { ui.uiDV = dt.DefaultView; } } else { EnumerableRowCollection<DataRow> query = from row in dt.AsEnumerable() where row.Field<string>("Sheet Name").Length > 0 select row; ui.uiDV = query.AsDataView(); } ui.uiDataGrid.ItemsSource = ui.uiDV; }
当前实现的界面效果:DataGrid前三列设置为只读,分别展示图纸编号、图纸名称、图纸ID;后续列对应每个SheetSet分组,以复选框形式展示当前图纸与该分组的关联状态,支持直接勾选修改。
当前DataGrid的行筛选功能符合预期,但测试发现修改复选框状态时,对应的CellEditEnding触发事件偶发无法正常执行。
查阅相关参考资料时发现,多数DataGrid实现是在XAML中完成绑定而非后台代码,且现有示例多为绑定实体对象的ObservableCollection,与当前业务场景不匹配。判断需要调整为XAML绑定方式,但不清楚如何针对“需支持列动态增减”的业务场景做正确的绑定配置,需要获取对应实现思路与问题排查指导。
当前编写的XAML中与DataGrid相关的代码如下:
<DataGrid x:Name="uiDataGrid" Grid.ColumnSpan="2" Grid.Row="3" Height="Auto" CellEditEnding="uiDataGrid_CellEditEnding"> <DataGrid.Resources> <Style TargetType="{x:Type DataGridColumnHeader}"> <Setter Property="Background" Value="Turquoise" /> <Setter Property="BorderBrush" Value="Black" /> <Setter Property="BorderThickness" Value="0,0,1,2" /> </Style> </DataGrid.Resources> </DataGrid>
内容的提问来源于stack exchange,提问作者Santiago Diaz
相关产品推荐
相关产品推荐

