You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:33:01