如何从ObservableCollection的SelectedItem反序列化JSON并绑定到DataGrid
实现方案
前置准备:定义部件实体类
首先创建和JSON字段匹配的部件数据模型:
public class Part { public string PartNum { get; set; } public string PartDescription { get; set; } public string PartReason { get; set; } public int PartQty { get; set; } }
方案1:MVVM 绑定实现(无后台代码,推荐)
该方案不需要写界面事件,通过属性通知自动联动,符合WPF开发规范。
步骤1:改造主列表实体类
给存储JSON的主实体加可通知的部件集合属性:
public class YourMainEntity : INotifyPropertyChanged { // 保留原有所有属性,此处省略 public string Parts { get; set; } // 原有存储JSON的字段 private ObservableCollection<Part> _partsList; public ObservableCollection<Part> PartsList { get => _partsList; set { _partsList = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
步骤2:ViewModel 中处理选中逻辑
在ViewModel的选中项属性变更时自动反序列化JSON:
private YourMainEntity _selectedItem; public YourMainEntity SelectedItem { get => _selectedItem; set { _selectedItem = value; OnPropertyChanged(); // 选中项变更时处理JSON反序列化 if (_selectedItem != null && !string.IsNullOrWhiteSpace(_selectedItem.Parts)) { // 用System.Text.Json反序列化,用Newtonsoft.Json写法类似 var partList = JsonSerializer.Deserialize<List<Part>>(_selectedItem.Parts, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); _selectedItem.PartsList = new ObservableCollection<Part>(partList); } else { _selectedItem?.PartsList?.Clear(); } } }
步骤3:XAML 绑定DataGrid
直接绑定选中项的部件集合即可:
<DataGrid ItemsSource="{Binding SelectedItem.PartsList}" AutoGenerateColumns="False" IsReadOnly="True"> <DataGrid.Columns> <DataGridTextColumn Header="部件编号" Binding="{Binding PartNum}"/> <DataGridTextColumn Header="部件描述" Binding="{Binding PartDescription}"/> <DataGridTextColumn Header="部件原因" Binding="{Binding PartReason}"/> <DataGridTextColumn Header="数量" Binding="{Binding PartQty}"/> </DataGrid.Columns> </DataGrid>
方案2:SelectionChanged 后台代码实现
如果不需要用MVVM,直接修复后台事件写法即可:
XAML 示例
给主列表和DataGrid添加名称标识:
<!-- 主列表 --> <ListView x:Name="MainList" SelectionChanged="MainList_OnSelectionChanged" ItemsSource="{Binding YourObservableCollection}"> <!-- 原有列表模板 --> </ListView> <!-- 部件DataGrid --> <DataGrid x:Name="PartsGrid" AutoGenerateColumns="False" IsReadOnly="True"> <!-- 列定义和方案1完全一致 --> </DataGrid>
后台事件代码
private void MainList_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (MainList.SelectedItem is not YourMainEntity selectedItem) { PartsGrid.ItemsSource = null; return; } if (string.IsNullOrWhiteSpace(selectedItem.Parts)) { PartsGrid.ItemsSource = null; return; } // 反序列化JSON并绑定 var partList = JsonSerializer.Deserialize<IEnumerable<Part>>(selectedItem.Parts, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); PartsGrid.ItemsSource = partList; }
常见问题排查
- 反序列化报错:检查JSON字段名和
Part类属性名是否匹配,开启PropertyNameCaseInsensitive配置可忽略大小写差异 - DataGrid无显示:确认
AutoGenerateColumns设为False,避免自动生成多余列 - 选中无反应:检查主列表的
SelectedItem绑定/事件挂载是否正常
内容的提问来源于stack exchange,提问作者WPFAdvocate
相关产品推荐
相关产品推荐

