diff --git a/插件库/Lskj.Control/GridControlEx.cs b/插件库/Lskj.Control/GridControlEx.cs index d38de1a..c5af21f 100644 --- a/插件库/Lskj.Control/GridControlEx.cs +++ b/插件库/Lskj.Control/GridControlEx.cs @@ -412,6 +412,94 @@ namespace Lskj.Control this.gridView.DoubleClick += OnShowImageDoubleClick; ; #endregion } + /// + /// 保存前反写多表头数据源 + /// + public void callbackUpdData() + { + try + { + // 获取动态多表头的Grid控件数据源 (假设为DataTable) + DataTable updatedTable = CustomGroupBandEx.gridControl.DataSource as DataTable; + if (updatedTable == null) return; + + // 获取原始的GridControl的数据源 + DataTable originalDataTable = this.gridControl.DataSource as DataTable; + if (originalDataTable == null) return; + + // 获取分组相关的列定义 + GridColumnModel GroupPrimary = ColumnList.FirstOrDefault(o => o.IsCustomGroupPrimary); + GridColumnModel GroupFieldprimary = ColumnList.FirstOrDefault(o => o.IsCustomGroupField == 1); + List GroupField = ColumnList.Where(o => o.IsCustomGroupField == 2).ToList(); + + if (GroupPrimary == null || GroupFieldprimary == null || !GroupField.Any()) return; + + // 遍历每一行更新回原始数据表 + foreach (DataRow updatedRow in updatedTable.Rows) + { + string primaryKeyValue = updatedRow[GroupPrimary.FieldName]?.ToString(); + + // 根据主键定位原始表中的行集合 + var originalRows = originalDataTable.AsEnumerable() + .Where(row => row.Field(GroupPrimary.FieldName) == primaryKeyValue).ToList(); + + if (!originalRows.Any()) continue; // 若没有匹配的行,跳过 + + // 遍历动态表头的Band及子列 + foreach (GridBand band in CustomGroupBandEx.BandedView.Bands) + { + if (band.Caption == "基本信息") continue; // 跳过普通列Band + + string groupFieldPrimaryValue = band.Caption; + + foreach (BandedGridColumn column in band.Columns) + { + var subField = column.Tag as GridColumnModel; + if (subField == null) continue; + + string dynamicFieldName = column.FieldName; + object updatedValue = updatedRow[dynamicFieldName]; + + // 精确匹配原数据源对应的单行 + DataRow targetRow = originalRows.FirstOrDefault(r => + r.Field(GroupFieldprimary.FieldName) == groupFieldPrimaryValue); + + // 若找到行,则更新该行对应的字段 + if (targetRow != null && originalDataTable.Columns.Contains(subField.FieldName)) + { + targetRow[subField.FieldName] = updatedValue; + } + else if (targetRow == null) + { + // 若没找到,说明可能为新增数据行,插入新行(若业务需要) + DataRow newOriginalRow = originalDataTable.NewRow(); + newOriginalRow[GroupPrimary.FieldName] = primaryKeyValue; + newOriginalRow[GroupFieldprimary.FieldName] = groupFieldPrimaryValue; + + foreach (var col in ColumnList.Where(x => !x.IsCustomGroupField.Equals(1) && !x.IsCustomGroupPrimary)) + { + if (updatedTable.Columns.Contains(col.FieldName) && originalDataTable.Columns.Contains(col.FieldName)) + { + newOriginalRow[col.FieldName] = updatedRow[col.FieldName]; + } + } + + if (originalDataTable.Columns.Contains(subField.FieldName)) + { + newOriginalRow[subField.FieldName] = updatedValue; + } + + originalDataTable.Rows.Add(newOriginalRow); + } + } + } + } + } + catch (Exception ex) + { + MessageBox.Show("保存失败:" + ex.Message); + } + } /// /// 说明:单元格合并 @@ -6554,7 +6642,200 @@ namespace Lskj.Control } } } + // 调用动态构建方法 + if (CustomGroupBandEx != null) + { + DataTable currentDataSource = gridView.GridControl.DataSource as DataTable; + if (currentDataSource != null) + { + BuildDynamicGroupedColumns(CustomGroupBandEx, currentDataSource); + } + } } + /// + /// 构建多表头格式 + /// + /// + /// + private void BuildDynamicGroupedColumns(BandedGridControlEx bandedGridControlEx, DataTable originalDataSource) + { + // 数据源改变时必须重复执行此逻辑 + bandedGridControlEx.BandedView.OptionsView.ColumnAutoWidth = false; + + // 获取你的定义的主键、分组列、聚合数据列 + GridColumnModel GroupPrimary = ColumnList.FirstOrDefault(o => o.IsCustomGroupPrimary); + GridColumnModel GroupFieldprimary = ColumnList.FirstOrDefault(o => o.IsCustomGroupField == 1); + List GroupField = ColumnList.Where(o => o.IsCustomGroupField == 2).ToList(); + + if (GroupPrimary == null || GroupFieldprimary == null || !GroupField.Any()) + return; // 数据不足直接退出 + + // 清理现有结构 + bandedGridControlEx.BandedView.Bands.Clear(); + bandedGridControlEx.BandedView.Columns.Clear(); + + // 保留其他非聚合列 + List normalColumns = ColumnList.Where(o => !o.IsCustomGroupPrimary && o.IsCustomGroupField == 0).ToList(); + + // 创建正常列的Band + GridBand normalBand = new GridBand() { Caption = "基本信息" }; + bandedGridControlEx.BandedView.Bands.Add(normalBand); + + // 添加正常列到Band中 + foreach (var normalCol in normalColumns) + { + if (originalDataSource.Columns.Contains(normalCol.FieldName)) + { + BandedGridColumn col = new BandedGridColumn() + { + FieldName = normalCol.FieldName, + Caption = normalCol.FieldText, + Width = normalCol.Width, + Visible = true, + Tag = normalCol, + MinWidth = normalCol.Width, + MaxWidth = normalCol.Width, + OptionsColumn = { FixedWidth = true } // <-- 明确设置此属性 + }; + + normalBand.Columns.Add(col); + bandedGridControlEx.BandedView.Columns.Add(col); + } + } + + // 动态获取需要聚合的列 + var dynamicHeaders = originalDataSource.AsEnumerable() + .Select(r => r.Field(GroupFieldprimary.FieldName)) + .Distinct().Where(x => !string.IsNullOrEmpty(x)).ToList(); + + // 为每个动态表头生成GridBand,并添加子列 + foreach (string headerName in dynamicHeaders) + { + GridBand dynamicBand = new GridBand() { Caption = headerName }; + bandedGridControlEx.BandedView.Bands.Add(dynamicBand); + + foreach (var subField in GroupField) + { + string dynamicFieldName = $"{headerName}_{subField.FieldName}"; + + BandedGridColumn subColumn = new BandedGridColumn() + { + FieldName = dynamicFieldName, + Caption = subField.FieldText, + Visible = true, + Tag = subField, + Width = subField.Width, // 如果有特定宽度也可以赋值,若无则忽略 + OptionsColumn = { FixedWidth = true } // <-- 明确设置固定宽度 + }; + + dynamicBand.Columns.Add(subColumn); + bandedGridControlEx.BandedView.Columns.Add(subColumn); + } + } + + // 构建最终动态数据源 + DataTable dynamicDataTable = BuildDynamicDataSource(originalDataSource, GroupPrimary, GroupFieldprimary, GroupField, normalColumns, dynamicHeaders); + bandedGridControlEx.gridControl.DataSource = dynamicDataTable; + + // 最后再强制刷新布局 + bandedGridControlEx.BandedView.LayoutChanged(); + } + + /// + /// 构建数据源 + /// + /// + /// + /// + /// + /// + /// + /// + private DataTable BuildDynamicDataSource(DataTable originalDataSource, + GridColumnModel GroupPrimary, + GridColumnModel GroupFieldprimary, + List GroupField, + List normalColumns, + List dynamicHeaders) + { + try + { + DataTable dtResult = new DataTable(); + + // 添加主键列 + if (!dtResult.Columns.Contains(GroupPrimary.FieldName)) + dtResult.Columns.Add(GroupPrimary.FieldName, typeof(string)); + + // 添加普通列,仅当原数据源存在时才添加 + foreach (var col in normalColumns) + { + if (originalDataSource.Columns.Contains(col.FieldName)) + dtResult.Columns.Add(col.FieldName, typeof(string)); + } + + // 添加动态列 (改为string类型避免异常) + foreach (string header in dynamicHeaders) + { + foreach (var subField in GroupField) + { + string dynamicFieldName = $"{header}_{subField.FieldName}"; + if (!dtResult.Columns.Contains(dynamicFieldName)) + dtResult.Columns.Add(dynamicFieldName, typeof(string)); // <-- 此处已修改为string + } + } + + // 根据主键聚合数据 + var groupedData = originalDataSource.AsEnumerable() + .GroupBy(row => row.Field(GroupPrimary.FieldName)); + + foreach (var group in groupedData) + { + DataRow newRow = dtResult.NewRow(); + + // 主键列赋值 + DataRow firstRow = group.First(); + newRow[GroupPrimary.FieldName] = firstRow[GroupPrimary.FieldName]; + + // 普通列赋值(需判断原数据源中存在) + foreach (var col in normalColumns) + { + if (originalDataSource.Columns.Contains(col.FieldName)) + newRow[col.FieldName] = firstRow[col.FieldName]; + } + + // 动态聚合列赋值 + foreach (var header in dynamicHeaders) + { + var matchedRow = group.FirstOrDefault(r => r.Field(GroupFieldprimary.FieldName) == header); + foreach (var subField in GroupField) + { + string dynamicFieldName = $"{header}_{subField.FieldName}"; + + object value = DBNull.Value; + + if (matchedRow != null && originalDataSource.Columns.Contains(subField.FieldName)) + { + value = matchedRow[subField.FieldName]?.ToString(); // 明确转换为string,避免类型错误 + } + + newRow[dynamicFieldName] = value; + } + } + + dtResult.Rows.Add(newRow); + } + + return dtResult; + } + catch (Exception ex) + { + // 最好将异常记录下来 + Console.WriteLine(ex.Message); + return null; + } + } + + #endregion #region 绑定表格树结构弹出框