using System.Collections.Generic; using System.Drawing; using System; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; using DPumpHydr.WinFrmUI.WenSkin.Json.Utilities; using System.Linq; using System.IO; namespace DPumpHydr.WinFrmUI.WenSkin; public class Ini { private IniGroupCollection items; public Ini() { } public Ini(string path) : this(path, Encoding.UTF8) { } public Ini(string path, Encoding encoding) { Path = path; Encoding = encoding; Load(path, encoding); } public string? this[string name] { get => GetItem(name); set { var item = Items.SelectMany(t => t.Items)?.ToList().Find(t => t.Name?.ToLower() == name.ToLower()); if (item == null) { AddItem(null, name, value); } else { item.Value = value; } } } public string? this[string key, string name] { get => Items[key]?.Items[name]?.Value; set { //获取Group if (Items[key] is not IniGroup group) { group = this.Items.Add(key); } if (group.Items[name] is not IniItem iniItem) { iniItem = group.Items.Add(name, value); } iniItem.Value = value; } } #region 公有属性 public string FileName => System.IO.Path.GetFileName(Path); /// /// 路径 /// public string Path { get; private set; } /// /// 编码方式 /// public Encoding Encoding { get; private set; } /// /// 内容 /// public string Text => string.Join("\r\n", Items.Select(g => g.Text)); #endregion /// /// 加载(默认UTF8编码) /// /// public void Load(string path) => Load(path, Encoding.UTF8); /// /// 加载( 指定文件编码) /// /// /// public void Load(string path, Encoding encoding) { Items.Clear(); if (!File.Exists(path)) return; string[] texts = File.ReadAllLines(path, encoding); IniGroup? group = null; foreach (var text in texts) { //选项 string t = text.Replace(" ", ""); var idx = text.IndexOf("="); //添加组 if (t.StartsWith("[") && t.EndsWith("]")) { group = Items.Add(text.Substring(text.IndexOf("[") + 1, text.IndexOf("]") - 1)); continue; } else if (Items.Count == 0) { group = Items.Add(null); } //添加选项 if (t.StartsWith("!") || t.StartsWith(";") || t.StartsWith("]") || t.StartsWith("//") || string.IsNullOrEmpty(t)) { group?.Items.Add(null, text); } else if (idx == -1) { group?.Items.Add(null, text); } else if (idx == 0) { group?.Items.Add("", text); } else if (idx > 0) { group?.Items.Add(text.Substring(0, idx), text.Substring(idx + 1)); } } } /// /// 添加注释 /// /// /// public void AddRemark(string groupName, string value) => AddItem(groupName, null, value); /// /// 添加选项 /// /// /// /// public void AddItem(string? groupName, string? name, string? value) { var g = this.Items[groupName]; g ??= this.Items.Add(groupName); g.Items.Add(name, value); } /// /// 获取选项 /// /// 组名称 /// 名称 /// public string? GetItem(string groupName, string name) => Items[groupName]?.Items[name]?.Value; /// /// 获取选项值 /// /// 名称 /// public string? GetItem(string name) => Items.SelectMany(t => t.Items)?.ToList().Find(t => t.Name?.ToLower() == name.ToLower())?.Value; /// /// 保存 /// public void Save() { SaveAs(Path); } /// /// 另存为 /// /// public void SaveAs(string path) { SaveAs(path, Encoding); } /// /// 另存为(指定文件编码) /// /// 路径 /// 文件编码 public void SaveAs(string path, Encoding encoding) { File.WriteAllText(path, Text, encoding); } /// /// 选项 /// public IniGroupCollection Items => items ??= new IniGroupCollection(this); /// /// 组 /// public class IniGroup { private readonly IniGroupCollection owner; private IniItemCollection? items; public IniGroup(IniGroupCollection owner, string? name) { this.owner = owner; Name = name; } public Ini Ini => this.owner.Ini; /// /// 名称 /// public string? Name { get; private set; } /// /// 选项合集 /// public IniItemCollection Items => items ??= new IniItemCollection(this); /// /// 内容 /// public string Text => (string.IsNullOrWhiteSpace(Name) ? "" : $"[{Name}]\r\n") + string.Join("\r\n", Items.Select(x => x.Text)); } /// /// 组合计 /// public class IniGroupCollection : List { private readonly Ini owner; public IniGroupCollection(Ini owner) { this.owner = owner; } /// /// Ini /// public Ini Ini => this.owner; /// /// 获取选项 /// /// /// public IniGroup? this[string? name] => Find(a => a.Name?.ToUpper() == name?.ToUpper()); /// /// 添加选项 /// /// /// public IniGroup Add(string? name) { var g = new IniGroup(this, name); if (name is null) { this.Insert(0, g); } else { Add(g); } return g; } } /// /// 选项 /// public class IniItem { private readonly IniItemCollection owner; public IniItem(IniItemCollection owner, string? name, string? value) { this.owner = owner; Name = name; Value = value; } public Ini Ini => owner.Ini; public IniItemCollection Owner => owner; public int Index => owner.IndexOf(this); /// /// 名称 /// public string? Name { get; set; } /// /// 值 /// public string? Value { get; set; } /// /// 文本 /// public string? Text => string.IsNullOrWhiteSpace(Name) ? (string.IsNullOrWhiteSpace(Value) || Value.StartsWith('!') || Value.StartsWith(';') ? Value : (";" + Value)) : $"{Name}={Value}"; /// /// 是否是注释行 /// public bool IsRemarkLine => string.IsNullOrWhiteSpace(this.Name); } /// /// 选项合集 /// public class IniItemCollection : List { private readonly IniGroup owner; public IniItemCollection(IniGroup owner) { this.owner = owner; } public Ini Ini => owner.Ini; public IniItem? this[string name] => Find(a => a.Name?.ToUpper() == name?.ToUpper()); public IniItem Add(string? name, string? value) { var item = new IniItem(this, name, value); this.Add(item); return item; } } /// /// 弹出编辑窗口 /// public void Show() => IniFormShow(); /// /// 弹出编辑窗口 /// public void IniFormShow() { var fm = new Form() { Width = 925, Height = 571, Text = $"INI可视化编辑器 - 珠海森云科技出品 - {this.FileName} - {this.Encoding.EncodingName}", StartPosition = FormStartPosition.CenterScreen, }; fm.Controls.Add(new IniControl(this) { Dock = DockStyle.Fill }); fm.ShowDialog(); } public static StringFormat StringConters { get; set; } = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap) { LineAlignment = StringAlignment.Center, Trimming = StringTrimming.EllipsisCharacter }; public class IniControl : Control { private Ini Ini; public IniControl(Ini ini) { this.Ini = ini; this.Size = new Size(900, 540); this.BackColor = Color.White; Initcom(); if (ini != null) Load(); } private FlowLayoutPanel Flow; private void Initcom() { Button button = new Button() { Text = "保存 应用", Dock = DockStyle.Bottom, }; button.Click += (s, e) => { Ini.Save(); MessageBox.Show("保存成功!"); }; Flow = new FlowLayoutPanel() { Dock = DockStyle.Fill, AutoScroll = true, FlowDirection = FlowDirection.TopDown, WrapContents = false, }; this.Controls.Add(Flow); this.Controls.Add(button); } public IniItem Selected => SelectedControl.IniItem; public IniItemControl SelectedControl { get; private set; } private void Load() { foreach (var ini in Ini.Items) { var groupBox = new GroupBox() { Text = ini.Name ?? "Default (Is not group name)", ForeColor = Color.DarkOrchid, AutoSize = true, }; var flow = new FlowLayoutPanel() { AutoSize = true, FlowDirection = FlowDirection.TopDown, Dock = DockStyle.Fill, }; foreach (var item in ini.Items) { var control = new IniItemControl(this, flow, item); control.Click += (s, e) => { if (this.SelectedControl != null) this.SelectedControl.SelectColor = Color.White; control.SelectColor = Color.DarkGray; this.SelectedControl = control; }; flow.Controls.Add(control); } groupBox.Controls.Add(flow); Flow.Controls.Add(groupBox); } } } public class IniItemControl : Control { private readonly IniControl owner; private readonly FlowLayoutPanel flow; private readonly IniItem iniItem; public IniItemControl(IniControl owner, FlowLayoutPanel flow, IniItem iniItem) { base.SetStyle( ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); base.UpdateStyles(); this.BackColor = Color.Transparent; this.owner = owner; this.flow = flow; this.iniItem = iniItem; this.Height = 30; this.Width = 870; this.Margin = new Padding(1, 0, 1, 0); this.Name = iniItem.Name; this.Text = iniItem.Text; menuStrip.Items.Add("注释", null, (s, e) => { var item = new IniItem(IniItem.Owner, null, ";注释"); this.IniItem.Owner.Insert(this.IniItem.Index, item); var control = new IniItemControl(owner, flow, item); this.flow.Controls.Add(control); this.flow.Controls.SetChildIndex(control, this.IniItem.Index - 1); }); menuStrip.Items.Add("插入", null, (s, e) => { var item = new IniItem(IniItem.Owner, "Name", "Value"); this.IniItem.Owner.Insert(this.IniItem.Index, item); var control = new IniItemControl(owner, flow, item); this.flow.Controls.Add(control); this.flow.Controls.SetChildIndex(control, this.IniItem.Index - 1); }); menuStrip.Items.Add("添加", null, (s, e) => { var item = new IniItem(IniItem.Owner, "Name", "Value"); this.IniItem.Owner.Add(item); var control = new IniItemControl(owner, flow, item); this.flow.Controls.Add(control); }); menuStrip.Items.Add("删除", null, (s, e) => { this.IniItem.Owner.Remove(this.IniItem); this.Dispose(); }); this.ContextMenuStrip = menuStrip; } private readonly ContextMenuStrip menuStrip = new ContextMenuStrip(); private Color selectColor = Color.White; public IniItem IniItem => iniItem; public Color SelectColor { get => selectColor; set { selectColor = value; this.BackColor = value; } } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); this.BackColor = SelectColor; } protected override void OnMouseEnter(EventArgs e) { base.OnMouseEnter(e); this.BackColor = Color.LightGray; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); var g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿 g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.CompositingQuality = CompositingQuality.HighQuality; if (IniItem.IsRemarkLine) { var valueRec = new RectangleF(0, 0, Width, Height); g.DrawString(IniItem.Value, Font, Brushes.Green, valueRec, StringConters); } else { var nameRec = new RectangleF(0, 0, 145, Height); var valueRec = new RectangleF(150, 0, Width - 150, Height); g.DrawString(IniItem.Name, Font, Brushes.DodgerBlue, nameRec, StringConters); g.DrawString(IniItem.Value, Font, Brushes.Black, valueRec, StringConters); } } protected override void OnMouseClick(MouseEventArgs e) { base.OnMouseClick(e); if (IniItem.IsRemarkLine) { ShowTextBox(Width, 0); } else { if (new RectangleF(0, 0, 145, Height).Contains(e.Location)) { ShowTextBox(145, 0, false); } else { ShowTextBox(Width - 150, 150); } } } private void ShowTextBox(int width, int x, bool isValue = true) { var tb = new TextBox() { Width = width, Text = isValue ? IniItem.Value : IniItem.Name, ForeColor = IniItem.IsRemarkLine ? Color.Green : Color.Black, }; tb.Location = new Point(x, (this.Height - tb.Height) / 2); tb.LostFocus += (s, e) => { tb.Dispose(); }; tb.TextChanged += (s, e) => { if (isValue) IniItem.Value = tb.Text; else IniItem.Name = tb.Text; }; tb.KeyDown += (s, e) => { if (e.KeyCode == Keys.Enter) { tb.Dispose(); } }; this.Controls.Add(tb); tb.Select(); } } }