i18n准备
This commit is contained in:
2026-02-23 14:14:35 +08:00
parent a019c27c8b
commit 1704ad37d2
7 changed files with 362 additions and 9 deletions
+52
View File
@@ -0,0 +1,52 @@
using System.Globalization;
using System.Threading;
using Ink_Canvas.Properties;
namespace Ink_Canvas.Helpers
{
/// <summary>
/// i18n 本地化辅助:设置/获取当前 UI 语言,便于后续从配置切换语言。
/// </summary>
public static class LocalizationHelper
{
/// <summary>
/// 当前 UI 语言(如 "zh-CN", "en-US")。未设置时使用系统当前 UI 语言。
/// </summary>
public static CultureInfo CurrentCulture
{
get => Thread.CurrentThread.CurrentUICulture;
set
{
if (value == null) return;
Thread.CurrentThread.CurrentUICulture = value;
Strings.Culture = value;
}
}
/// <summary>
/// 使用指定语言名称设置当前 UI 语言(如 "zh-CN", "en-US")。
/// 若名称无效则保持当前语言不变。
/// </summary>
public static bool TrySetCulture(string cultureName)
{
try
{
var culture = CultureInfo.GetCultureInfo(cultureName);
CurrentCulture = culture;
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 获取本地化字符串。优先使用强类型属性,未知键时用此方法。
/// </summary>
public static string GetString(string key)
{
return Strings.GetString(key);
}
}
}
+5
View File
@@ -565,6 +565,11 @@
<ItemGroup>
<Compile Remove="AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Strings.en-US.resx">
<LogicalName>Ink_Canvas.Properties.Strings.en-US.resources</LogicalName>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Remove="MainWindow.xaml~RF6c3144.TMP" />
<None Remove="Resources\Cursors\Cursor.cur" />
+2 -1
View File
@@ -8,6 +8,7 @@
xmlns:Controls="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
xmlns:controls="clr-namespace:Ink_Canvas.Controls"
xmlns:Windows="clr-namespace:Ink_Canvas.Windows"
xmlns:props="clr-namespace:Ink_Canvas.Properties"
mc:Ignorable="d"
AllowsTransparency="True"
WindowStyle="None"
@@ -145,7 +146,7 @@
<StackPanel>
<!-- Plugins -->
<Button Width="40" Height="40" Margin="0,5,0,0" Style="{StaticResource NavButton}"
Click="NavPlugins_Click" Tag="plugins" ToolTip="插件">
Click="NavPlugins_Click" Tag="plugins" ToolTip="{x:Static props:Strings.Nav_Plugins}">
<Image Width="20" Height="20">
<Image.Source>
<DrawingImage>
+2 -8
View File
@@ -19,14 +19,8 @@ using System.Windows;
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
// i18n: 默认/回退语言为简体中文,与 Strings.resx 默认文案一致。
[assembly: System.Resources.NeutralResourcesLanguage("zh-CN", System.Resources.UltimateResourceFallbackLocation.MainAssembly)]
[assembly: ThemeInfo(
+74
View File
@@ -0,0 +1,74 @@
//------------------------------------------------------------------------------
// <auto-generated>
// i18n 字符串资源 - 由 Strings.resx 生成,请勿直接编辑。
// 修改文案请编辑 Strings.resx 及对应语言的 Strings.{Culture}.resx。
// </auto-generated>
//------------------------------------------------------------------------------
using System.Globalization;
using System.Resources;
using System.Runtime.CompilerServices;
namespace Ink_Canvas.Properties
{
/// <summary>
/// 本地化字符串资源,用于 i18n。当前 UI 语言由 Thread.CurrentThread.CurrentUICulture 决定。
/// </summary>
[CompilerGenerated]
public static class Strings
{
private static ResourceManager _resourceMan;
private static CultureInfo _resourceCulture;
/// <summary>
/// 用于此类资源查找的 ResourceManager。
/// </summary>
public static ResourceManager ResourceManager
{
get
{
if (ReferenceEquals(_resourceMan, null))
{
var temp = new ResourceManager("Ink_Canvas.Properties.Strings", typeof(Strings).Assembly);
_resourceMan = temp;
}
return _resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture,以在此强类型资源类中进行资源查找。
/// 若不设置,则使用 Thread.CurrentThread.CurrentUICulture。
/// </summary>
public static CultureInfo Culture
{
get => _resourceCulture;
set => _resourceCulture = value;
}
/// <summary>
/// 根据键获取本地化字符串;若未设置 Culture 则使用当前线程 CurrentUICulture。
/// </summary>
public static string GetString(string key)
{
var culture = _resourceCulture ?? CultureInfo.CurrentUICulture;
return ResourceManager.GetString(key, culture);
}
public static string Nav_Plugins => ResourceManager.GetString(nameof(Nav_Plugins), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "插件";
public static string Nav_Startup => ResourceManager.GetString(nameof(Nav_Startup), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "启动设置";
public static string Nav_Canvas => ResourceManager.GetString(nameof(Nav_Canvas), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "画布设置";
public static string Nav_CrashAction => ResourceManager.GetString(nameof(Nav_CrashAction), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "崩溃处理";
public static string Nav_Gesture => ResourceManager.GetString(nameof(Nav_Gesture), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "手势";
public static string Nav_InkRecognition => ResourceManager.GetString(nameof(Nav_InkRecognition), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "墨迹识别";
public static string Nav_PPT => ResourceManager.GetString(nameof(Nav_PPT), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "PPT";
public static string Nav_Advanced => ResourceManager.GetString(nameof(Nav_Advanced), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "高级";
public static string Nav_Automation => ResourceManager.GetString(nameof(Nav_Automation), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "自动化";
public static string Nav_RandomWindow => ResourceManager.GetString(nameof(Nav_RandomWindow), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "随机选人";
public static string Nav_Theme => ResourceManager.GetString(nameof(Nav_Theme), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "主题";
public static string Nav_Shortcuts => ResourceManager.GetString(nameof(Nav_Shortcuts), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "快捷键";
public static string Nav_About => ResourceManager.GetString(nameof(Nav_About), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "关于";
public static string App_Title => ResourceManager.GetString(nameof(App_Title), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "InkCanvasforClass";
public static string Booth_Resolution_Tooltip => ResourceManager.GetString(nameof(Booth_Resolution_Tooltip), _resourceCulture ?? CultureInfo.CurrentUICulture) ?? "展台/截图分辨率";
}
}
+106
View File
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Nav_Plugins" xml:space="preserve">
<value>Plugins</value>
</data>
<data name="Nav_Startup" xml:space="preserve">
<value>Startup</value>
</data>
<data name="Nav_Canvas" xml:space="preserve">
<value>Canvas</value>
</data>
<data name="Nav_CrashAction" xml:space="preserve">
<value>Crash Action</value>
</data>
<data name="Nav_Gesture" xml:space="preserve">
<value>Gesture</value>
</data>
<data name="Nav_InkRecognition" xml:space="preserve">
<value>Ink Recognition</value>
</data>
<data name="Nav_PPT" xml:space="preserve">
<value>PPT</value>
</data>
<data name="Nav_Advanced" xml:space="preserve">
<value>Advanced</value>
</data>
<data name="Nav_Automation" xml:space="preserve">
<value>Automation</value>
</data>
<data name="Nav_RandomWindow" xml:space="preserve">
<value>Random Picker</value>
</data>
<data name="Nav_Theme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="Nav_Shortcuts" xml:space="preserve">
<value>Shortcuts</value>
</data>
<data name="Nav_About" xml:space="preserve">
<value>About</value>
</data>
<data name="App_Title" xml:space="preserve">
<value>InkCanvasforClass</value>
</data>
<data name="Booth_Resolution_Tooltip" xml:space="preserve">
<value>Booth / Screenshot resolution</value>
</data>
</root>
+121
View File
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Nav_Plugins" xml:space="preserve">
<value>插件</value>
<comment>设置侧栏 - 插件</comment>
</data>
<data name="Nav_Startup" xml:space="preserve">
<value>启动设置</value>
<comment>设置侧栏 - 启动设置</comment>
</data>
<data name="Nav_Canvas" xml:space="preserve">
<value>画布设置</value>
<comment>设置侧栏 - 画布设置</comment>
</data>
<data name="Nav_CrashAction" xml:space="preserve">
<value>崩溃处理</value>
<comment>设置侧栏 - 崩溃处理</comment>
</data>
<data name="Nav_Gesture" xml:space="preserve">
<value>手势</value>
<comment>设置侧栏 - 手势</comment>
</data>
<data name="Nav_InkRecognition" xml:space="preserve">
<value>墨迹识别</value>
<comment>设置侧栏 - 墨迹识别</comment>
</data>
<data name="Nav_PPT" xml:space="preserve">
<value>PPT</value>
<comment>设置侧栏 - PPT</comment>
</data>
<data name="Nav_Advanced" xml:space="preserve">
<value>高级</value>
<comment>设置侧栏 - 高级</comment>
</data>
<data name="Nav_Automation" xml:space="preserve">
<value>自动化</value>
<comment>设置侧栏 - 自动化</comment>
</data>
<data name="Nav_RandomWindow" xml:space="preserve">
<value>随机选人</value>
<comment>设置侧栏 - 随机选人</comment>
</data>
<data name="Nav_Theme" xml:space="preserve">
<value>主题</value>
<comment>设置侧栏 - 主题</comment>
</data>
<data name="Nav_Shortcuts" xml:space="preserve">
<value>快捷键</value>
<comment>设置侧栏 - 快捷键</comment>
</data>
<data name="Nav_About" xml:space="preserve">
<value>关于</value>
<comment>设置侧栏 - 关于</comment>
</data>
<data name="App_Title" xml:space="preserve">
<value>InkCanvasforClass</value>
<comment>主窗口标题</comment>
</data>
<data name="Booth_Resolution_Tooltip" xml:space="preserve">
<value>展台/截图分辨率</value>
<comment>展台分辨率选项卡提示</comment>
</data>
</root>