Skip to content

refactor: 用 TrySetValue 替代 ByTag 开关语句#3156

Merged
LinQingYuu merged 3 commits into
devfrom
refactor/TrySetValue
Jun 17, 2026
Merged

refactor: 用 TrySetValue 替代 ByTag 开关语句#3156
LinQingYuu merged 3 commits into
devfrom
refactor/TrySetValue

Conversation

@LuLu-ling

@LuLu-ling LuLu-ling commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary by Sourcery

重构 UI 配置绑定机制,将控件数值变更统一通过集中化的配置服务进行处理。

增强内容:

  • 使用共享的 ConfigService.TrySetValue 帮助方法替换各页面中基于标签到配置键的 switch 语句,通过键来设置配置值。
  • 在实例、启动、UI、游戏链接、游戏管理以及启动器杂项页面中统一 SetByTag 帮助方法,以减少重复代码并集中配置更新逻辑。
  • 扩展 ConfigService,新增类型感知的 TrySetValue 方法,在应用配置变更时支持枚举类型以及可选的上下文参数(例如实例路径)。
Original summary in English

Summary by Sourcery

Refactor UI configuration bindings to route control value changes through a centralized configuration service.

Enhancements:

  • Replace page-specific tag-to-config switch statements with a shared ConfigService.TrySetValue helper for setting configuration values by key.
  • Unify SetByTag helpers across instance, launch, UI, game link, game manage, and launcher misc pages to reduce duplication and centralize config update logic.
  • Extend ConfigService with a type-aware TrySetValue method that handles enums and optional context arguments (such as instance paths) when applying configuration changes.

@LuLu-ling LuLu-ling requested a review from a team June 16, 2026 07:58
@pcl-ce-automation pcl-ce-automation Bot added 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查 size: L PR 大小评估:大型 labels Jun 16, 2026
@sourcery-ai

sourcery-ai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Reviewer's Guide

重构多个 UI 设置页面,将基于 Tag 的配置更新委托给集中化的 ConfigService.TrySetValue 辅助方法,替换本地的 switch/Tag 映射逻辑,并在 ConfigService 中加入对枚举类型的安全处理。

通过 ConfigService.TrySetValue 路由 UI Tag 变更的时序图

sequenceDiagram
    actor User
    participant Control as MyControl
    participant Page as PageSetup
    participant ConfigService
    participant ConfigItem

    User->>Control: change value
    Control->>Page: RadioBoxChange/TextBoxChange/SliderChange/CheckBoxChange
    Page->>Page: SetByTag(tag, value)
    Page->>ConfigService: TrySetValue(tag, value, argument)
    ConfigService->>ConfigService: TryGetConfigItemNoType(tag, out item)
    alt item found
        ConfigService->>ConfigItem: [item.Type.IsEnum && value is not string]
        ConfigItem->>ConfigItem: SetValueNoType(Enum.ToObject(item.Type, value), argument)
        else non enum or string
        ConfigItem->>ConfigItem: SetValueNoType(value, argument)
    else item not found
        ConfigService-->>Page: return (no-op)
    end
Loading

File-Level Changes

Change Details Files
将实例设置页面中本地的 tag-to-config switch 逻辑替换为共享的 SetByTag 辅助方法,该方法使用 ConfigService.TrySetValue,并支持每个实例的参数。
  • 引入一个私有静态的 SetByTag 辅助方法,用实例路径作为参数调用 ConfigService.TrySetValue
  • 重构 RadioBoxChange,解析 tag/value 片段并转发给 SetByTag,而不是手动解析 ArgConfig<int>
  • 重构 TextBoxChangeSliderChangeComboChangeCheckBoxChange,将 tag 和控件值直接委托给 SetByTag,移除内联 switch 表达式以及对 ArgConfig 的使用。
Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml.cs
通过 ConfigService.TrySetValue 统一启动器 UI 相关设置更新,替代大型基于 Tag 的 switch 语句。
  • 在文件中添加 ConfigService 的 using 指令。
  • SetByTag 的实现简化为单行代码,将 tag 和 value 委托给 ConfigService.TrySetValue,移除对 UI Tag 的显式 switch
Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.cs
重构启动设置页面,通过 SetByTag 使用共享的 ConfigService.TrySetValue,移除专用的 SetLaunchByTag 逻辑。
  • 在文件中添加 ConfigService 的 using 指令。
  • 更新 RadioBoxChangeTextBoxChangeTextArgumentTitle_OnTextChangedSliderChangeComboChangeCheckBoxChange,使其调用 SetByTag 而非 SetLaunchByTag
  • 移除 SetLaunchByTag 方法,改为使用委托给 ConfigService.TrySetValueSetByTag 辅助方法。
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.cs
重构游戏链接设置页面,将控件变更通过 ConfigService.TrySetValue 进行路由,替换 SetGameLinkByTag 中的 switch
  • 在文件中添加 ConfigService 的 using 指令。
  • 更新 TextBoxChangeComboBoxChangeCheckBoxChange,使其使用 tag 和控件值调用 SetByTag
  • 用委托给 ConfigService.TrySetValueSetByTag 辅助方法替换 SetGameLinkByTag
Plain Craft Launcher 2/Pages/PageSetup/PageSetupGameLink.xaml.cs
重构游戏管理设置页面,使用 ConfigService.TrySetValue 处理基于 Tag 的配置变更。
  • 在文件中添加 ConfigService 的 using 指令。
  • 更新 CheckBoxChangeSliderChangeComboChange,使其调用 SetByTag 而非 SetGameManageByTag
  • 移除 SetGameManageByTag,并引入委托给 ConfigService.TrySetValueSetByTag 辅助方法。
Plain Craft Launcher 2/Pages/PageSetup/PageSetupGameManage.xaml.cs
重构启动器杂项设置页面,将所有基于 Tag 的配置变更委托给 ConfigService.TrySetValue
  • 更新 ComboChangeRadioBoxChangeCheckBoxChangeSliderChange,使其调用 SetByTag 而非 SetMiscByTag
  • 用委托给 ConfigService.TrySetValueSetByTag 辅助方法替换 SetMiscByTag
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLauncherMisc.xaml.cs
扩展 ConfigService,增加一个泛型的 TrySetValue 辅助方法,用于执行类型安全、支持枚举、基于 Tag 的配置更新。
  • 添加 TrySetValue(key, value, argument) 方法,在不需要泛型类型的情况下查找 ConfigItem
  • 实现逻辑:当 key 未注册时静默返回。
  • 为枚举类型的配置项添加特殊处理,对非字符串值在调用 SetValueNoType 前通过 Enum.ToObject 转换;否则直接传入该值以及可选参数。
PCL.Core/App/Configuration/ConfigService.cs

Tips and commands

Interacting with Sourcery

  • 触发一次新的审查: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成一个 GitHub issue: 通过回复某条审查评论让 Sourcery 从中创建 issue。你也可以在审查评论中回复 @sourcery-ai issue 来从该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题的任意位置写入 @sourcery-ai,即可随时生成标题。也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 概要: 在 pull request 描述正文的任意位置写入 @sourcery-ai summary,即可在你想要的位置生成 PR 概要。你也可以在 pull request 中评论 @sourcery-ai summary 来(重新)生成概要。
  • 生成审查者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时(重新)生成审查者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 忽略所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。特别适用于你想从一个全新的审查开始的场景——别忘了再评论 @sourcery-ai review 来触发新的审查!

Customizing Your Experience

前往你的 dashboard 以:

  • 启用或禁用审查功能,例如 Sourcery 生成的 pull request 概要、审查者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查指令。
  • 调整其他审查设置。

Getting Help

Original review guide in English

Reviewer's Guide

Refactors multiple UI settings pages to delegate tag-based configuration updates to the centralized ConfigService.TrySetValue helper, replacing local switch/Tag-mapping logic and adding enum-safe type handling in ConfigService.

Sequence diagram for routing UI tag changes through ConfigService.TrySetValue

sequenceDiagram
    actor User
    participant Control as MyControl
    participant Page as PageSetup
    participant ConfigService
    participant ConfigItem

    User->>Control: change value
    Control->>Page: RadioBoxChange/TextBoxChange/SliderChange/CheckBoxChange
    Page->>Page: SetByTag(tag, value)
    Page->>ConfigService: TrySetValue(tag, value, argument)
    ConfigService->>ConfigService: TryGetConfigItemNoType(tag, out item)
    alt item found
        ConfigService->>ConfigItem: [item.Type.IsEnum && value is not string]
        ConfigItem->>ConfigItem: SetValueNoType(Enum.ToObject(item.Type, value), argument)
        else non enum or string
        ConfigItem->>ConfigItem: SetValueNoType(value, argument)
    else item not found
        ConfigService-->>Page: return (no-op)
    end
Loading

File-Level Changes

Change Details Files
Replace local tag-to-config switch logic in instance setup page with a shared SetByTag helper that uses ConfigService.TrySetValue and supports per-instance argument.
  • Introduce a private static SetByTag helper that calls ConfigService.TrySetValue with the instance path as the argument.
  • Refactor RadioBoxChange to parse tag/value segments and forward them to SetByTag instead of manually resolving ArgConfig.
  • Refactor TextBoxChange, SliderChange, ComboChange, and CheckBoxChange to delegate tag and control values directly to SetByTag, removing inline switch expressions and ArgConfig usage.
Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml.cs
Unify launcher UI-related setting updates through ConfigService.TrySetValue instead of a large tag-based switch statement.
  • Add ConfigService using directive to the file.
  • Simplify SetByTag implementation to a one-liner that delegates tag and value to ConfigService.TrySetValue, removing the explicit switch over UI tags.
Plain Craft Launcher 2/Pages/PageSetup/PageSetupUI.xaml.cs
Refactor launch settings page to use the shared ConfigService.TrySetValue via SetByTag, removing specialized SetLaunchByTag logic.
  • Add ConfigService using directive to the file.
  • Update RadioBoxChange, TextBoxChange, TextArgumentTitle_OnTextChanged, SliderChange, ComboChange, and CheckBoxChange to call SetByTag instead of SetLaunchByTag.
  • Remove the SetLaunchByTag method and replace it with a SetByTag helper that delegates to ConfigService.TrySetValue.
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.cs
Refactor game link settings page to route control changes through ConfigService.TrySetValue, replacing SetGameLinkByTag switches.
  • Add ConfigService using directive to the file.
  • Update TextBoxChange, ComboBoxChange, and CheckBoxChange to call SetByTag with tag and control values.
  • Replace SetGameLinkByTag with a SetByTag helper that delegates to ConfigService.TrySetValue.
Plain Craft Launcher 2/Pages/PageSetup/PageSetupGameLink.xaml.cs
Refactor game management settings page to use ConfigService.TrySetValue for tag-based configuration changes.
  • Add ConfigService using directive to the file.
  • Update CheckBoxChange, SliderChange, and ComboChange to call SetByTag instead of SetGameManageByTag.
  • Remove SetGameManageByTag and introduce a SetByTag helper that delegates to ConfigService.TrySetValue.
Plain Craft Launcher 2/Pages/PageSetup/PageSetupGameManage.xaml.cs
Refactor miscellaneous launcher settings page to delegate all tag-based config mutations to ConfigService.TrySetValue.
  • Update ComboChange, RadioBoxChange, CheckBoxChange, and SliderChange to call SetByTag instead of SetMiscByTag.
  • Replace SetMiscByTag with a SetByTag helper that delegates to ConfigService.TrySetValue.
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLauncherMisc.xaml.cs
Extend ConfigService with a generic TrySetValue helper that performs type-safe, enum-aware, tag-based configuration updates.
  • Add TrySetValue(key, value, argument) method that looks up a ConfigItem without requiring a generic type.
  • Implement logic to silently return when the key is not registered.
  • Add special handling for enum-typed config items, converting non-string values via Enum.ToObject before calling SetValueNoType; otherwise pass the value directly with the optional argument.
PCL.Core/App/Configuration/ConfigService.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并留了一些整体层面的反馈:

  • 一些 SetByTag 的调用方现在会直接把 slider.Valuedouble)或其他弱类型的值传入 ConfigService.TrySetValue;建议要么在调用处显式转换为目标数值类型(例如 (int)slider.Value),要么扩展 TrySetValue 使其支持数值类型之间的转换,以避免在 SetValueNoType 中出现运行时类型不匹配。
  • SetByTag 方法接受的是 string tag,但调用时使用的是 control.Tag?.ToString(),该值可能为 null;更安全的做法是在调用前对 null 进行检查,或者让 TrySetValue/SetByTag 能够优雅地处理 null/空键,以避免在标签缺失或配置错误时产生意料之外的异常。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several `SetByTag` callers now pass `slider.Value` (a `double`) or other loosely typed values directly into `ConfigService.TrySetValue`; consider either explicitly converting to the target numeric type at call sites (e.g., `(int)slider.Value`) or extending `TrySetValue` to handle numeric conversions to avoid runtime type mismatches in `SetValueNoType`.
- `SetByTag` methods accept `string tag` but are invoked with `control.Tag?.ToString()`, which may be `null`; it would be safer to either guard against `null` before calling or have `TrySetValue`/`SetByTag` gracefully handle `null`/empty keys to avoid unexpected exceptions when a tag is missing or misconfigured.

## Individual Comments

### Comment 1
<location path="PCL.Core/App/Configuration/ConfigService.cs" line_range="100-103" />
<code_context>
+    /// <param name="key">配置键</param>
+    /// <param name="value">配置值</param>
+    /// <param name="argument">上下文参数(实例路径等)</param>
+    public static void TrySetValue(string key, object value, object? argument = null)
+    {
+        if (!TryGetConfigItemNoType(key, out var item)) return;
+        if (item.Type.IsEnum && value is not string)
+            item.SetValueNoType(Enum.ToObject(item.Type, value), argument);
+        else
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Enum handling is covered, but non-enum numeric type mismatches may still be fragile.

`TrySetValue` now converts non-string values to enums via `Enum.ToObject`, which is good. For non-enum numeric types, though, it just forwards the boxed `value` to `SetValueNoType` without coercion. If `SetValueNoType` requires an exact type match (e.g., `double``int` or `long``int` not accepted), callers that previously cast explicitly may now fail or change behavior. Consider either performing basic numeric coercion here for primitive numeric types, or clearly documenting that callers must provide a correctly typed value and keep explicit casts at call sites.
</issue_to_address>

Sourcery 对开源项目免费 —— 如果你觉得这次评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • Several SetByTag callers now pass slider.Value (a double) or other loosely typed values directly into ConfigService.TrySetValue; consider either explicitly converting to the target numeric type at call sites (e.g., (int)slider.Value) or extending TrySetValue to handle numeric conversions to avoid runtime type mismatches in SetValueNoType.
  • SetByTag methods accept string tag but are invoked with control.Tag?.ToString(), which may be null; it would be safer to either guard against null before calling or have TrySetValue/SetByTag gracefully handle null/empty keys to avoid unexpected exceptions when a tag is missing or misconfigured.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several `SetByTag` callers now pass `slider.Value` (a `double`) or other loosely typed values directly into `ConfigService.TrySetValue`; consider either explicitly converting to the target numeric type at call sites (e.g., `(int)slider.Value`) or extending `TrySetValue` to handle numeric conversions to avoid runtime type mismatches in `SetValueNoType`.
- `SetByTag` methods accept `string tag` but are invoked with `control.Tag?.ToString()`, which may be `null`; it would be safer to either guard against `null` before calling or have `TrySetValue`/`SetByTag` gracefully handle `null`/empty keys to avoid unexpected exceptions when a tag is missing or misconfigured.

## Individual Comments

### Comment 1
<location path="PCL.Core/App/Configuration/ConfigService.cs" line_range="100-103" />
<code_context>
+    /// <param name="key">配置键</param>
+    /// <param name="value">配置值</param>
+    /// <param name="argument">上下文参数(实例路径等)</param>
+    public static void TrySetValue(string key, object value, object? argument = null)
+    {
+        if (!TryGetConfigItemNoType(key, out var item)) return;
+        if (item.Type.IsEnum && value is not string)
+            item.SetValueNoType(Enum.ToObject(item.Type, value), argument);
+        else
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Enum handling is covered, but non-enum numeric type mismatches may still be fragile.

`TrySetValue` now converts non-string values to enums via `Enum.ToObject`, which is good. For non-enum numeric types, though, it just forwards the boxed `value` to `SetValueNoType` without coercion. If `SetValueNoType` requires an exact type match (e.g., `double``int` or `long``int` not accepted), callers that previously cast explicitly may now fail or change behavior. Consider either performing basic numeric coercion here for primitive numeric types, or clearly documenting that callers must provide a correctly typed value and keep explicit casts at call sites.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread PCL.Core/App/Configuration/ConfigService.cs
@pcl-ce-automation pcl-ce-automation Bot added 🕑 等待合并 已处理完毕,正在等待代码合并入主分支 and removed 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查 labels Jun 17, 2026
@LinQingYuu LinQingYuu merged commit e9a05a7 into dev Jun 17, 2026
3 checks passed
@pcl-ce-automation pcl-ce-automation Bot added 👌 完成 相关问题已修复或功能已实现,计划在下次版本更新时正式上线 and removed 🕑 等待合并 已处理完毕,正在等待代码合并入主分支 labels Jun 17, 2026
@LinQingYuu LinQingYuu deleted the refactor/TrySetValue branch June 17, 2026 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: L PR 大小评估:大型 👌 完成 相关问题已修复或功能已实现,计划在下次版本更新时正式上线

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants