feat: 完善个人设置及表格功能
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
using Lskj.Control;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Lskj.Main
|
||||
{
|
||||
public partial class FrmPersonalSetting : BaseForm
|
||||
{
|
||||
private MainAppearanceSettings _settings;
|
||||
|
||||
public FrmPersonalSetting()
|
||||
{
|
||||
InitializeComponent();
|
||||
BuildDesignerControls();
|
||||
// 设计器只需要静态控件,不访问本地配置文件或运行时状态。
|
||||
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return;
|
||||
_settings = MainAppearanceSettingsStore.Load();
|
||||
LoadSettingsToControls();
|
||||
}
|
||||
|
||||
private void LoadSettingsToControls()
|
||||
{
|
||||
txtTopColor.Text = _settings.TopMenuBackground;
|
||||
txtLeftColor.Text = _settings.SidebarBackground;
|
||||
txtLeftSelectColor.Text = _settings.SidebarSelectedBackground;
|
||||
numTopFont.Value = Clamp(_settings.TopMenuFontSize, numTopFont.Minimum, numTopFont.Maximum);
|
||||
numLeftFont.Value = Clamp(_settings.LeftMenuFontSize, numLeftFont.Minimum, numLeftFont.Maximum);
|
||||
// An empty value means "use the program default". Keep the editor
|
||||
// visually empty while MainPanelControlEx2 still uses its fallback.
|
||||
if (!_settings.TopMenuFontConfigured) numTopFont.Text = string.Empty;
|
||||
if (!_settings.LeftMenuFontConfigured) numLeftFont.Text = string.Empty;
|
||||
UpdateColorPreview(txtTopColor, pnlTopPreview);
|
||||
UpdateColorPreview(txtLeftColor, pnlLeftPreview);
|
||||
UpdateColorPreview(txtLeftSelectColor, pnlLeftSelectPreview);
|
||||
}
|
||||
|
||||
private void SaveSettings()
|
||||
{
|
||||
int ignoredTopFont;
|
||||
int ignoredLeftFont;
|
||||
MainAppearanceSettingsStore.Save(new MainAppearanceSettings
|
||||
{
|
||||
TopMenuBackground = MainAppearanceSettingsStore.NormalizeColor(txtTopColor.Text, _settings.TopMenuBackground),
|
||||
SidebarBackground = MainAppearanceSettingsStore.NormalizeColor(txtLeftColor.Text, _settings.SidebarBackground),
|
||||
SidebarSelectedBackground = MainAppearanceSettingsStore.NormalizeColor(txtLeftSelectColor.Text, _settings.SidebarSelectedBackground),
|
||||
TopMenuFontSize = ParseFontEditorValue(numTopFont, MainAppearanceSettingsStore.DefaultTopMenuFontSize),
|
||||
LeftMenuFontSize = ParseFontEditorValue(numLeftFont, MainAppearanceSettingsStore.DefaultLeftMenuFontSize),
|
||||
TopMenuFontConfigured = TryParseFontEditorValue(numTopFont, out ignoredTopFont),
|
||||
LeftMenuFontConfigured = TryParseFontEditorValue(numLeftFont, out ignoredLeftFont)
|
||||
});
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ChooseColor(TextBox textBox, Panel preview)
|
||||
{
|
||||
Color current = MainAppearanceSettingsStore.ParseColor(textBox.Text, Color.White);
|
||||
using (ColorDialog dialog = new ColorDialog { Color = current, FullOpen = true })
|
||||
{
|
||||
if (dialog.ShowDialog(this) != DialogResult.OK) return;
|
||||
textBox.Text = MainAppearanceSettingsStore.FormatColor(dialog.Color);
|
||||
UpdateColorPreview(textBox, preview);
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateColorPreview(TextBox textBox, Panel preview)
|
||||
{
|
||||
if (preview != null) preview.BackColor = MainAppearanceSettingsStore.ParseColor(textBox.Text, Color.White);
|
||||
}
|
||||
|
||||
private static decimal Clamp(int value, decimal min, decimal max)
|
||||
{
|
||||
return Math.Min(max, Math.Max(min, value));
|
||||
}
|
||||
|
||||
private static bool TryParseFontEditorValue(NumericUpDown editor, out int value)
|
||||
{
|
||||
value = 0;
|
||||
int parsed;
|
||||
if (!int.TryParse((editor == null ? string.Empty : editor.Text ?? string.Empty).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out parsed)) return false;
|
||||
if (parsed < MainAppearanceSettingsStore.MinimumFontSize || parsed > MainAppearanceSettingsStore.MaximumFontSize) return false;
|
||||
value = parsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int ParseFontEditorValue(NumericUpDown editor, int fallback)
|
||||
{
|
||||
int value;
|
||||
return TryParseFontEditorValue(editor, out value) ? value : fallback;
|
||||
}
|
||||
|
||||
private void txtColor_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (sender == txtTopColor) UpdateColorPreview(txtTopColor, pnlTopPreview);
|
||||
else if (sender == txtLeftColor) UpdateColorPreview(txtLeftColor, pnlLeftPreview);
|
||||
else if (sender == txtLeftSelectColor) UpdateColorPreview(txtLeftSelectColor, pnlLeftSelectPreview);
|
||||
}
|
||||
|
||||
private void btnTopColor_Click(object sender, EventArgs e) { ChooseColor(txtTopColor, pnlTopPreview); }
|
||||
private void btnLeftColor_Click(object sender, EventArgs e) { ChooseColor(txtLeftColor, pnlLeftPreview); }
|
||||
private void btnLeftSelectColor_Click(object sender, EventArgs e) { ChooseColor(txtLeftSelectColor, pnlLeftSelectPreview); }
|
||||
private void btnSave_Click(object sender, EventArgs e) { SaveSettings(); }
|
||||
private void btnCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); }
|
||||
private void btnReset_Click(object sender, EventArgs e) { _settings = MainAppearanceSettingsStore.Defaults(); LoadSettingsToControls(); }
|
||||
private void navAppearance_Click(object sender, EventArgs e) { ShowPage(pnlAppearance); }
|
||||
private void navFonts_Click(object sender, EventArgs e) { ShowPage(pnlFonts); }
|
||||
}
|
||||
|
||||
internal sealed class MainAppearanceSettings
|
||||
{
|
||||
public string TopMenuBackground;
|
||||
public string SidebarBackground;
|
||||
public string SidebarSelectedBackground;
|
||||
public int TopMenuFontSize;
|
||||
public int LeftMenuFontSize;
|
||||
public bool TopMenuFontConfigured;
|
||||
public bool LeftMenuFontConfigured;
|
||||
}
|
||||
|
||||
internal static class MainAppearanceSettingsStore
|
||||
{
|
||||
internal const int DefaultTopMenuFontSize = 9;
|
||||
internal const int DefaultLeftMenuFontSize = 12;
|
||||
internal const int MinimumFontSize = 8;
|
||||
internal const int MaximumFontSize = 24;
|
||||
// WinForms uses a separate file so changing the WPF shell settings does not
|
||||
// unexpectedly alter the transitional WinForms main panel.
|
||||
private const string FileName = "WinFromShellAppearance.ini";
|
||||
private const string TopColorKey = "TopMenuBackground=";
|
||||
private const string LeftColorKey = "SidebarBackground=";
|
||||
private const string LeftSelectedColorKey = "SidebarSelectedBackground=";
|
||||
private const string TopFontKey = "TopMenuFontSize=";
|
||||
private const string LeftFontKey = "LeftMenuFontSize=";
|
||||
|
||||
public static MainAppearanceSettings Defaults()
|
||||
{
|
||||
return new MainAppearanceSettings
|
||||
{
|
||||
TopMenuBackground = "#1F4B99",
|
||||
SidebarBackground = "#272D51",
|
||||
SidebarSelectedBackground = "#348ED8",
|
||||
TopMenuFontSize = DefaultTopMenuFontSize,
|
||||
LeftMenuFontSize = DefaultLeftMenuFontSize,
|
||||
TopMenuFontConfigured = false,
|
||||
LeftMenuFontConfigured = false
|
||||
};
|
||||
}
|
||||
|
||||
public static MainAppearanceSettings Load()
|
||||
{
|
||||
MainAppearanceSettings result = Defaults();
|
||||
try
|
||||
{
|
||||
string path = GetPath();
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
// Create the WinForms-specific file on first run so the active
|
||||
// values are visible and editable from the Debug\Config folder.
|
||||
Save(result);
|
||||
return result;
|
||||
}
|
||||
foreach (string raw in File.ReadAllLines(path))
|
||||
{
|
||||
string line = (raw ?? string.Empty).Trim();
|
||||
if (line.StartsWith(TopColorKey, StringComparison.OrdinalIgnoreCase)) result.TopMenuBackground = NormalizeColor(line.Substring(TopColorKey.Length), result.TopMenuBackground);
|
||||
else if (line.StartsWith(LeftColorKey, StringComparison.OrdinalIgnoreCase)) result.SidebarBackground = NormalizeColor(line.Substring(LeftColorKey.Length), result.SidebarBackground);
|
||||
else if (line.StartsWith(LeftSelectedColorKey, StringComparison.OrdinalIgnoreCase)) result.SidebarSelectedBackground = NormalizeColor(line.Substring(LeftSelectedColorKey.Length), result.SidebarSelectedBackground);
|
||||
else if (line.StartsWith(TopFontKey, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
int value;
|
||||
if (TryParseFont(line.Substring(TopFontKey.Length), out value)) { result.TopMenuFontSize = value; result.TopMenuFontConfigured = true; }
|
||||
}
|
||||
else if (line.StartsWith(LeftFontKey, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
int value;
|
||||
if (TryParseFont(line.Substring(LeftFontKey.Length), out value)) { result.LeftMenuFontSize = value; result.LeftMenuFontConfigured = true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void Save(MainAppearanceSettings settings)
|
||||
{
|
||||
if (settings == null) return;
|
||||
string path = GetPath();
|
||||
string[] oldLines = new string[0];
|
||||
try { if (File.Exists(path)) oldLines = File.ReadAllLines(path); } catch (Exception) { }
|
||||
string[] replacements =
|
||||
{
|
||||
TopColorKey + NormalizeColor(settings.TopMenuBackground, "#1F4B99"),
|
||||
LeftColorKey + NormalizeColor(settings.SidebarBackground, "#272D51"),
|
||||
LeftSelectedColorKey + NormalizeColor(settings.SidebarSelectedBackground, "#348ED8"),
|
||||
TopFontKey + (settings.TopMenuFontConfigured ? settings.TopMenuFontSize.ToString(CultureInfo.InvariantCulture) : string.Empty),
|
||||
LeftFontKey + (settings.LeftMenuFontConfigured ? settings.LeftMenuFontSize.ToString(CultureInfo.InvariantCulture) : string.Empty)
|
||||
};
|
||||
string[] keys = { TopColorKey, LeftColorKey, LeftSelectedColorKey, TopFontKey, LeftFontKey };
|
||||
var output = oldLines.ToList();
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
int index = output.FindIndex(x => (x ?? string.Empty).Trim().StartsWith(keys[i], StringComparison.OrdinalIgnoreCase));
|
||||
if (index >= 0) output[index] = replacements[i]; else output.Add(replacements[i]);
|
||||
}
|
||||
try
|
||||
{
|
||||
string dir = Path.GetDirectoryName(path);
|
||||
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
|
||||
File.WriteAllLines(path, output.ToArray());
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
public static string NormalizeColor(string value, string fallback)
|
||||
{
|
||||
return FormatColor(ParseColor(value, ParseColor(fallback, Color.Black)));
|
||||
}
|
||||
|
||||
public static Color ParseColor(string value, Color fallback)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) return fallback;
|
||||
string text = value.Trim();
|
||||
if (!text.StartsWith("#", StringComparison.Ordinal) || text.Length != 7) return fallback;
|
||||
byte r, g, b;
|
||||
if (!byte.TryParse(text.Substring(1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out r) || !byte.TryParse(text.Substring(3, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out g) || !byte.TryParse(text.Substring(5, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out b)) return fallback;
|
||||
return Color.FromArgb(r, g, b);
|
||||
}
|
||||
|
||||
public static string FormatColor(Color color)
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "#{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
private static bool TryParseFont(string value, out int result)
|
||||
{
|
||||
result = 0;
|
||||
return int.TryParse((value ?? string.Empty).Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out result)
|
||||
&& result >= MinimumFontSize && result <= MaximumFontSize;
|
||||
}
|
||||
|
||||
private static string GetPath()
|
||||
{
|
||||
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user