1.描述
假设:后端查询返回的是一个DataTable类型的结果
问题:发现
ExistingProductionInfoDgvItemSource = dt;

或者
ExistingProductionInfoDgvItemSource = dt.DefaultView均无法显示数据。。。
绑定为DataView类型会显示一段奇怪的东西出来,这里忘记截图了
2.代码
2.1View
XML
<DataGrid
x:Name="ExistingProductionInfoDgv"
SelectedItem="{Binding SelectedConfProduct, Mode=TwoWay}"
ItemsSource="{Binding ExistingProductionInfoDgvItemSource.DefaultView}"
PointerReleased="ExistingProductionInfoDgv_OnPointerReleased"
AutoGenerateColumns="False"
GridLinesVisibility="All"/>
2.2ViewModel 的绑定
cs
private DataTable _existingProductionInfoDgvItemSource = new DataTable();
public DataTable ExistingProductionInfoDgvItemSource
{
get => _existingProductionInfoDgvItemSource;
set
{
_existingProductionInfoDgvItemSource = value;
NotifyChanged();
// 数据-赋值 传递dt-value给View的后置代码
// DataTableUpdated?.Invoke(this,value);
DataTableUpdated?.Invoke(this, _existingProductionInfoDgvItemSource);
}
}
// 数据更新事件(联动View生成列)--代码后置
public event EventHandler<DataTable> DataTableUpdated;
//查询赋值
#region 初始化查询-刷新
//获取数据
private void GetAllConf_Product()
{
try
{
var db = new DBHelperTest();
var dtResult = db.GetAllConf_ProductDataTable(); // 数据库查询
// 直接赋值,触发DataTableUpdated事件
ExistingProductionInfoDgvItemSource = dtResult ?? new DataTable();
}
catch (Exception ex)
{
CustomMessageBoxView.ShowAsync("数据加载失败", $"错误:{ex.Message}");
}
}
#endregion
2.3代码后置
cs
private ProductSettingViewModel _vm;
public ProductSetting()
{
this.DataContext = new ProductSettingViewModel();
InitializeComponent();
this.PointerReleased += ProductSetting_OnPointerReleased;
// 1. 绑定ViewModel
// this.DataContext = new ProductSettingViewModel();
_vm = new ProductSettingViewModel();
DataContext = _vm;
// 2. 订阅事件-执行列生成
ExistingProductionInfoDgv.Loaded += ExistingProductionInfoDgv_Loaded;
}
#region 现有产品信息Dgv1生成列
// 3. DataGrid加载完成后自动触发(核心:此时DataGrid一定非null)
private void ExistingProductionInfoDgv_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
// 订阅ViewModel的数据更新事件(数据就绪后生成列)
_vm.DataTableUpdated += Vm_DataTableUpdated;
// 初始数据生成:如果ViewModel已查询到数据,直接生成列
if (_vm.ExistingProductionInfoDgvItemSource?.Rows.Count > 0)
{
GenerateColumns(_vm.ExistingProductionInfoDgvItemSource);
}
}
// 4. 生成列的核心方法(仅View层处理,完全对应示例逻辑)
private void GenerateColumns(DataTable dt)
{
// 清除旧列
ExistingProductionInfoDgv.Columns.Clear();
// 绑定数据源为DataView
ExistingProductionInfoDgv.ItemsSource = dt.DefaultView;
var columnNameMap = new Dictionary<string, string>
{
{ "ID", "序号" },
{ "Name", "产品名称" },
{ "Code", "产品识别码" },
{ "SOP_BarcodeParam", "产品扫码参数" },
{ "SOP_PartParam", "零件追溯参数" },
{ "SOP_WorkParam", "工序作业参数" },
{ "ProgramNum", "图号识别起始位" },
{ "StartNum", "图号识别位数" },
{ "CodeNum", "产品型号" },
{ "OrderProductionCode", "生产用号" }
// 后续需要添加其他字段映射,直接在这里加键值对即可
};
// 遍历列生成DataGrid列
foreach (DataColumn col in dt.Columns)
{
// 3. 根据字段名获取显示名(如果没有匹配的映射,默认用原字段名)
string displayHeader = columnNameMap.TryGetValue(col.ColumnName, out string name)
? name
: col.ColumnName;
DataGridColumn gridCol = col.DataType == typeof(bool)
? new DataGridCheckBoxColumn //创建复选框单元格
{
Header = displayHeader,
Binding = new Binding($"Row.ItemArray[{col.Ordinal}]")
}
: new DataGridTextColumn //创建文本框单元格
{
Header = displayHeader,
Binding = new Binding($"Row.ItemArray[{col.Ordinal}]")
};
ExistingProductionInfoDgv.Columns.Add(gridCol);
}
}
// 5. 响应ViewModel的数据更新(数据变化时重新生成列)
private void Vm_DataTableUpdated(object? sender, DataTable dt)
{
GenerateColumns(dt);
}
#endregion
3.效果

显示成功
4.修改
4.1过滤不需要的列
某一个表:
其中FieldName和FieldAttribute 是我不需要的数据库字段
在生成列的方法中:使用HashSet设定一组需要的列名,
// 1. 定义需要显示的列名(仅保留这三个)
var needShowColumns = new HashSet<string>
{
"ID",
"FieldDesc",
"FieldDataSource"
};
在声明列前使用if判断是否是需要的列即可
// 过滤不需要的列 if (!needShowColumns.Contains(col.ColumnName)) { continue; // 不生成该列,直接进入下一次循环 }
cs
private void ProductSettingDgv_GenerateColumns(DataTable dt)
{
ProductSettingDgv.Columns.Clear();
ProductSettingDgv.ItemsSource = dt.DefaultView;
// 1. 定义需要显示的列名(仅保留这三个)
var needShowColumns = new HashSet<string>
{
"ID",
"FieldDesc",
"FieldDataSource"
};
var columnNameMap = new Dictionary<string, string>()
{
{ "ID", "序号" },
{ "FieldDesc", "参数名称" },
{ "FieldDataSource", "参数设定值" },
};
//遍历生成DataGrid列
foreach (DataColumn col in dt.Columns)
{
// 过滤不需要的列
if (!needShowColumns.Contains(col.ColumnName))
{
continue; // 不生成该列,直接进入下一次循环
}
//根据数据库字段名,获取,Dgv2的列名
string displayHeader = columnNameMap.TryGetValue(col.ColumnName, out string name)
? name
: col.ColumnName;
//判断列的类型 ?复选框:文本
DataGridColumn gridcol = col.DataType == typeof(bool)
? new DataGridCheckBoxColumn
{
Header = displayHeader,
Binding = new Binding($"Row.ItemArray[{col.Ordinal}]")
}
: new DataGridTextColumn
{
Header = displayHeader,
Binding = new Binding($"Row.ItemArray[{col.Ordinal}]")
};
ProductSettingDgv.Columns.Add(gridcol);
}
}