wpf 基于 JSON 的扩展配置 (Extended Config)” 功能

实现 "基于 JSON 的扩展配置 (Extended Config)" 功能的详细教程。我们将按照 Model (数据层) -> ViewModel (逻辑层) -> View (UI层) 的顺序进行。

这个功能的 核心思想 是:

  1. 数据库 存的是一个长字符串(JSON 格式)。
  2. 界面 显示的是一个表格(List 列表)。
  3. ViewModel 负责在"字符串"和"列表"之间来回转换。

第一步:修改数据库实体模型 (Model)

我们需要在数据库表中增加一列,用来专门存这些"乱七八糟"的扩展配置。

  1. 打开文件 : D:\BZW\MyQucikDevFrameWork\QuickNetFrameWork\QuickWpf\QuickWpf.Core\Models\Business\Recipe.cs

  2. 添加代码 :
    在 Recipe 类中,添加一个 ExtendedAttributes 字符串属性。

    // 在 Recipe 类内部添加:
    [SugarTable("Recipes")]
    public class Recipe
    {
    // ... 其他已有属性 ...

    复制代码
     /// <summary>
     /// 扩展属性 (JSON 格式),用于存储不固定的配方参数
     /// ColumnDataType = "TEXT" 告诉数据库这是一个长文本字段,
     能存很多内容
     /// </summary>
     [SugarColumn(ColumnDataType = "TEXT", IsNullable = 
     true)]
     public string ExtendedAttributes { get; set; } = "{}
     "; // 默认为空 JSON 对象

    }

第二步:创建列表项辅助类 (Helper Class)

界面上的表格(DataGrid)需要绑定到一个对象列表。我们需要定义这个"对象"长什么样(比如有 Key, Value, Description 三列)。

  1. 打开文件 : D:\BZW\MyQucikDevFrameWork\QuickNetFrameWork\QuickWpf\QuickWpf.Modules.Hardware\ViewModels\RecipeViewModel.cs (注:你也可以新建一个单独的 .cs 文件,但为了方便,我们先放在 ViewModel 文件里)

  2. 添加代码 :
    在 RecipeViewModel 类的 外面 (也就是 namespace 里面),定义 ExtendedAttributeItem 类。

    namespace QuickWpf.Modules.Hardware.ViewModels
    {
    // --- 新增这个类 ---
    public class ExtendedAttributeItem : BindableBase
    {
    private string _key = string.Empty;
    public string Key
    {
    get => _key;
    set => SetProperty(ref _key, value);
    }

    复制代码
         private string _value = string.Empty;
         public string Value 
         { 
             get => _value; 
             set => SetProperty(ref _value, value); 
         }
    
         private string _description = string.Empty;
         public string Description 
         { 
             get => _description; 
             set => SetProperty(ref _description, value); 
         }
     }
     // ------------------
    
     public class RecipeViewModel : BindableBase 
     {
         // ...
     }

    }

第三步:在 ViewModel 中编写逻辑 (核心步骤)

这是最关键的一步,我们要处理"加载时把 JSON 变列表"和"保存时把列表变 JSON"。

  1. 打开文件 : D:\BZW\MyQucikDevFrameWork\QuickNetFrameWork\QuickWpf\QuickWpf.Modules.Hardware\ViewModels\RecipeViewModel.cs

  2. 修改代码 :在 RecipeViewModel 类内部添加以下内容。

    2.1 定义列表属性和命令

    复制代码
    // 1. 定义绑定的数据源
    private ObservableCollection<ExtendedAttributeItem> 
    _extendedAttributesList;
    public ObservableCollection<ExtendedAttributeItem> 
    ExtendedAttributesList
    {
        get => _extendedAttributesList;
        set => SetProperty(ref _extendedAttributesList, 
        value);
    }
    
    // 2. 定义选中项(用于删除功能)
    private ExtendedAttributeItem? 
    _selectedExtendedAttribute;
    public ExtendedAttributeItem? SelectedExtendedAttribute
    {
        get => _selectedExtendedAttribute;
        set => SetProperty(ref _selectedExtendedAttribute, 
        value);
    }
    
    // 3. 定义按钮命令
    public DelegateCommand AddExtendedAttributeCommand { 
    get; }
    public DelegateCommand RemoveExtendedAttributeCommand { 
    get; }

    2.2 在构造函数中初始化命令

    复制代码
    public RecipeViewModel(...)
    {
        // ... 其他初始化 ...
        
        // 初始化命令
        AddExtendedAttributeCommand = new DelegateCommand
        (OnAddExtendedAttribute);
        RemoveExtendedAttributeCommand = new DelegateCommand
        (OnRemoveExtendedAttribute);
    }

    2.3 实现加载逻辑 (JSON -> List) 找到 LoadRecipeDetails 方法(或者你加载配方详情的地方),添加转换逻辑:

    复制代码
    private void LoadRecipeDetails()
    {
        // ... 加载其他属性 ...
    
        // --- 新增:加载扩展属性 ---
        try
        {
            if (string.IsNullOrWhiteSpace(SelectedRecipe.
            ExtendedAttributes) || SelectedRecipe.
            ExtendedAttributes == "{}")
            {
                // 如果是空的,就创建一个新列表
                ExtendedAttributesList = new 
                ObservableCollection<ExtendedAttributeItem>
                ();
            }
            else
            {
                // 使用 System.Text.Json 将字符串反序列化为对象
                列表
                var list = System.Text.Json.JsonSerializer.
                Deserialize<List<ExtendedAttributeItem>>
                (SelectedRecipe.ExtendedAttributes);
                ExtendedAttributesList = new 
                ObservableCollection<ExtendedAttributeItem>
                (list);
            }
        }
        catch
        {
            // 如果解析失败(比如格式坏了),就重置为空列表,防止报
            错
            ExtendedAttributesList = new 
            ObservableCollection<ExtendedAttributeItem>();
        }
    }

    2.4 实现保存逻辑 (List -> JSON) 找到 OnSave 方法,添加转换逻辑:

    复制代码
    private void OnSave()
    {
        if (SelectedRecipe != null)
        {
            // --- 新增:保存扩展属性 ---
            if (ExtendedAttributesList != null)
            {
                // 将对象列表序列化为 JSON 字符串,存回 Recipe 实
                体
                SelectedRecipe.ExtendedAttributes = System.
                Text.Json.JsonSerializer.Serialize
                (ExtendedAttributesList);
            }
            
            // ... 执行数据库保存 ...
            _databaseService.Db.Storageable(SelectedRecipe).
            ExecuteCommand();
        }
    }

    2.5 实现增删行逻辑

    复制代码
    private void OnAddExtendedAttribute()
    {
        if (ExtendedAttributesList == null) 
            ExtendedAttributesList = new 
            ObservableCollection<ExtendedAttributeItem>();
            
        // 添加一行默认数据
        ExtendedAttributesList.Add(new ExtendedAttributeItem 
        { Key = "New Key", Value = "", Description = "" });
    }
    
    private void OnRemoveExtendedAttribute()
    {
        if (SelectedExtendedAttribute != null)
        {
            ExtendedAttributesList.Remove
            (SelectedExtendedAttribute);
        }
    }

第四步:在 XAML 中添加界面 (View)

最后,我们需要在界面上画出这个表格。

  1. 打开文件 : D:\BZW\MyQucikDevFrameWork\QuickNetFrameWork\QuickWpf\QuickWpf.Modules.Hardware\Views\RecipePage.xaml

  2. 添加代码 :
    找到 TabControl 部分,添加一个新的 TabItem 。

    <TabItem Header="Extended Config">
    <Grid Margin="0,8,0,0">
    <Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    复制代码
         <!-- 1. 顶部工具栏:添加/删除按钮 -->
         <!-- Visibility 绑定:只有在编辑模式(IsEditing=True)下
         才显示 -->
         <StackPanel Orientation="Horizontal" Margin="0,0,0,
         8" 
                     Visibility="{Binding IsEditing, 
                     Converter={StaticResource 
                     BoolToVisConverter}}">
             
             <Button Command="{Binding 
             AddExtendedAttributeCommand}" 
                     Content="Add Attribute" 
                     Style="{DynamicResource MahApps.Styles.
                     Button.Square.Accent}" 
                     Margin="0,0,8,0"/>
                     
             <Button Command="{Binding 
             RemoveExtendedAttributeCommand}" 
                     Content="Remove" 
                     Style="{DynamicResource MahApps.Styles.
                     Button.Square}"/>
         </StackPanel>
    
         <!-- 2. 数据表格 -->
         <DataGrid Grid.Row="1" 
                   ItemsSource="{Binding 
                   ExtendedAttributesList}" 
                   SelectedItem="{Binding 
                   SelectedExtendedAttribute}" 
                   AutoGenerateColumns="False" 
                   CanUserAddRows="False"
                   IsReadOnly="{Binding IsEditing, 
                   Converter={StaticResource 
                   InvertBooleanConverter}}">
                   <!-- IsReadOnly: 如果不是编辑模式,表格就只
                   读 -->
    
             <DataGrid.Columns>
                 <!-- Key 列 -->
                 <DataGridTextColumn Binding="{Binding Key}
                 " Header="Key" Width="150"/>
                 <!-- Value 列 -->
                 <DataGridTextColumn Binding="{Binding 
                 Value}" Header="Value" Width="*"/>
                 <!-- Description 列 -->
                 <DataGridTextColumn Binding="{Binding 
                 Description}" Header="Description" 
                 Width="*"/>
             </DataGrid.Columns>
         </DataGrid>
     </Grid>
    </TabItem>

总结

做完这四步,流程就通了:

  1. 用户 点击"Edit" -> 点击"Add Attribute" -> 表格里多了一行 -> 输入 Key="Speed", Value="100" 。
  2. ViewModel 里的 ExtendedAttributesList 多了一个对象。
  3. 用户 点击"Save"。
  4. ViewModel 把 List 变成字符串 [{"Key":"Speed","Value":"100",...}] 。
  5. Model 把这个字符串存进数据库的 ExtendedAttributes 字段。
  6. 下次 加载 时,反过来把字符串变回 List 显示在表格上。
相关推荐
jnrjian1 天前
text index 查看index column index定义 index 刷新频率 index视图
数据库·oracle
韶博雅1 天前
emcc升级
oracle
迷枫7121 天前
达梦数据库的体系架构
数据库·oracle·架构
夜晚打字声1 天前
9(九)Jmeter如何连接数据库
数据库·jmeter·oracle
NineData1 天前
NineData 智能数据管理平台新功能发布|2026 年 3 月
数据库·oracle·架构·dba·ninedata·数据复制·数据迁移工具
晓纪同学1 天前
WPF-03 第一个WPF程序
大数据·hadoop·wpf
不愿透露姓名的大鹏1 天前
Oracle归档日志爆满急救指南
linux·数据库·oracle·dba
jnrjian1 天前
Oracle text index 更新机制
oracle
jnrjian1 天前
Json text index 未读
oracle
光电大美美-见合八方中国芯1 天前
用于无色波分复用光网络的 10.7 Gb/s 反射式电吸收调制器与半导体光放大器单片集成
网络·后端·ai·云计算·wpf·信息与通信·模块测试