diff --git a/Runtime/Core/StyleSheetUI/StyleRefreshManager.cs b/Runtime/Core/StyleSheetUI/StyleRefreshManager.cs
new file mode 100644
index 0000000..a8048d8
--- /dev/null
+++ b/Runtime/Core/StyleSheetUI/StyleRefreshManager.cs
@@ -0,0 +1,65 @@
+using System.Collections.Generic;
+
+using UnityEngine;
+
+namespace XericUI.Core.StyleSheetUI
+{
+ ///
+ /// 标记可被全局刷新的样式组件。
+ /// 实现此接口的组件应在 OnEnable 调用 RegisterForStyleRefresh,
+ /// 在 OnDisable 调用 UnregisterForStyleRefresh。
+ ///
+ public interface IStyleRefreshable
+ {
+ void RefreshStyle();
+ }
+
+ ///
+ /// 全局样式刷新管理器——维护所有活跃的 IStyleRefreshable 组件。
+ /// 当外部样式表文件更新后,调用 ForceRefreshAll() 可一键刷新所有组件。
+ ///
+ public static class StyleRefreshManager
+ {
+ private static readonly HashSet s_Components = new HashSet();
+
+ /// 注册一个样式组件
+ public static void Register(IStyleRefreshable component)
+ {
+ if (component != null)
+ s_Components.Add(component);
+ }
+
+ /// 注销一个样式组件
+ public static void Unregister(IStyleRefreshable component)
+ {
+ if (component != null)
+ s_Components.Remove(component);
+ }
+
+ ///
+ /// 强制刷新所有已注册的样式组件。
+ /// 先调用 StyleManager.ForceRefresh() 同步样式表数据,
+ /// 再遍历所有组件重新读取并应用样式值。
+ ///
+ public static void ForceRefreshAll()
+ {
+#if XERIC_STYLESHEET_ENABLED
+ XericLibrary.Runtime.SuperStyleSheet.StyleManager.ForceRefresh();
+#endif
+
+ int count = 0;
+ foreach (var c in s_Components)
+ {
+ try { c.RefreshStyle(); } catch { }
+ count++;
+ }
+
+#if UNITY_EDITOR
+ Debug.Log($"[StyleRefresh] 已刷新 {count} 个样式组件。");
+#endif
+ }
+
+ /// 当前注册的组件数
+ public static int RegisteredCount => s_Components.Count;
+ }
+}
diff --git a/Runtime/Core/StyleSheetUI/StyleRefreshManager.cs.meta b/Runtime/Core/StyleSheetUI/StyleRefreshManager.cs.meta
new file mode 100644
index 0000000..127e6ca
--- /dev/null
+++ b/Runtime/Core/StyleSheetUI/StyleRefreshManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 65395d6526aed354f9b5344410621aa9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/OverrideUI/XericStyleButton.cs b/Runtime/OverrideUI/XericStyleButton.cs
index 45e7ff5..fd8c5b7 100644
--- a/Runtime/OverrideUI/XericStyleButton.cs
+++ b/Runtime/OverrideUI/XericStyleButton.cs
@@ -14,7 +14,7 @@ namespace XericUI.OverrideUI
/// 替代 Unity 内置的 ColorBlock 和 SpriteState。
///
[AddComponentMenu("Xeric UI Vessel/UI/Style Button", 51)]
- public class XericStyleButton : Button
+ public class XericStyleButton : Button, IStyleRefreshable
{
#region 序列化字段
@@ -59,11 +59,14 @@ namespace XericUI.OverrideUI
m_ColorState?.SubscribeAll(OnStyleChanged);
m_TextureState?.SubscribeAll(OnStyleChanged);
+ StyleRefreshManager.Register(this);
ApplyForState(m_CurrentState);
}
protected override void OnDisable()
{
+ StyleRefreshManager.Unregister(this);
+
m_ColorState?.UnsubscribeAll(OnStyleChanged);
m_TextureState?.UnsubscribeAll(OnStyleChanged);
m_ColorState?.UnregisterAll();
@@ -92,6 +95,11 @@ namespace XericUI.OverrideUI
#region 样式应用
+ public void RefreshStyle()
+ {
+ ApplyForState(m_CurrentState, false);
+ }
+
private void ApplyForState(StyleSheetSelectionState state, bool instant = false)
{
// 颜色
@@ -134,6 +142,12 @@ namespace XericUI.OverrideUI
#region 组件替换
#if UNITY_EDITOR
+ [UnityEditor.MenuItem("CONTEXT/XericStyleButton/Xeric UI/强制刷新样式", false, 1)]
+ private static void ForceRefreshStyle(UnityEditor.MenuCommand command)
+ {
+ StyleRefreshManager.ForceRefreshAll();
+ }
+
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Xeric (Style)", true)]
private static bool ValidateReplaceToStyleButton(UnityEditor.MenuCommand command)
=> command.context is Button and not XericStyleButton;
diff --git a/Runtime/OverrideUI/XericStyleImage.cs b/Runtime/OverrideUI/XericStyleImage.cs
index e175f14..2a964d9 100644
--- a/Runtime/OverrideUI/XericStyleImage.cs
+++ b/Runtime/OverrideUI/XericStyleImage.cs
@@ -2,6 +2,7 @@ using UnityEngine;
using UnityEngine.UI;
using XericLibrary.Runtime.SuperStyleSheet;
+using XericUI.Core.StyleSheetUI;
using XericUI.Helper;
namespace XericUI.OverrideUI
diff --git a/Runtime/OverrideUI/XericStyleToggle.cs b/Runtime/OverrideUI/XericStyleToggle.cs
index 6c0b83a..5472e5c 100644
--- a/Runtime/OverrideUI/XericStyleToggle.cs
+++ b/Runtime/OverrideUI/XericStyleToggle.cs
@@ -13,7 +13,7 @@ namespace XericUI.OverrideUI
/// 额外支持 isOn 覆盖和 Checkmark 样式。
///
[AddComponentMenu("Xeric UI Vessel/UI/Style Toggle", 52)]
- public class XericStyleToggle : Toggle
+ public class XericStyleToggle : Toggle, IStyleRefreshable
{
#region 序列化字段
@@ -86,12 +86,15 @@ namespace XericUI.OverrideUI
m_CheckmarkStyle?.Register();
m_CheckmarkStyle.OnValueChanged += OnStyleChanged;
+ StyleRefreshManager.Register(this);
onValueChanged.AddListener(OnToggleValueChanged);
ApplyForState(m_CurrentState);
}
protected override void OnDisable()
{
+ StyleRefreshManager.Unregister(this);
+
onValueChanged.RemoveListener(OnToggleValueChanged);
m_ColorState?.UnsubscribeAll(OnStyleChanged);
@@ -130,6 +133,11 @@ namespace XericUI.OverrideUI
#region 样式应用
+ public void RefreshStyle()
+ {
+ ApplyForState(m_CurrentState, false);
+ }
+
private void ApplyForState(StyleSheetSelectionState state, bool instant = false)
{
// 颜色:On 覆盖优先
@@ -181,6 +189,12 @@ namespace XericUI.OverrideUI
#region 组件替换
#if UNITY_EDITOR
+ [UnityEditor.MenuItem("CONTEXT/XericStyleToggle/Xeric UI/强制刷新样式", false, 1)]
+ private static void ForceRefreshStyle(UnityEditor.MenuCommand command)
+ {
+ StyleRefreshManager.ForceRefreshAll();
+ }
+
[UnityEditor.MenuItem("CONTEXT/Toggle/Replace To/Xeric (Style)", true)]
private static bool ValidateReplaceToStyleToggle(UnityEditor.MenuCommand command)
=> command.context is Toggle and not XericStyleToggle;