* EnumEx: DisplayText特性改为原生的Description特性

This commit is contained in:
Sunny 2025-04-06 16:42:44 +08:00
parent 00897c5cc5
commit 0d989a75ea
18 changed files with 2736 additions and 77 deletions

View File

@ -249,9 +249,9 @@ namespace Sunny.UI
{
Angle angle = Angles[pieIndex][azIndex];
PointF pf = angle.Center;
if (Drawing.CalcDistance(e.Location, pf) > angle.Outer) continue;
if (Drawing.CalcDistance(e.Location, pf) < angle.Inner) continue;
double az = Drawing.CalcAngle(e.Location, pf);
if (e.Location.CalcDistance(pf) > angle.Outer) continue;
if (e.Location.CalcDistance(pf) < angle.Inner) continue;
double az = e.Location.CalcAngle(pf);
if (az >= angle.Start && az <= angle.Start + angle.Sweep)
{
SetPieAndAzIndex(pieIndex, azIndex);

View File

@ -274,9 +274,9 @@ namespace Sunny.UI
if (!e.Location.InRect(rect)) continue;
PointF pf = new PointF(rect.Left + rect.Width / 2.0f, rect.Top + rect.Height / 2.0f);
if (Drawing.CalcDistance(e.Location, pf) * 2 > rect.Width) continue;
if (e.Location.CalcDistance(pf) * 2 > rect.Width) continue;
double az = Drawing.CalcAngle(e.Location, pf);
double az = e.Location.CalcAngle(pf);
for (int azIndex = 0; azIndex < Option.Series[pieIndex].Data.Count; azIndex++)
{
Angle angle = Angles[pieIndex][azIndex];

View File

@ -0,0 +1,743 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2023 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.Common.dll can be used for free under the MIT license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UBaseConfig.cs
* :
* : V3.1
* : 2020-01-01
*
* 2020-01-01: V2.2.0
******************************************************************************/
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Xml.Serialization;
namespace Sunny.UI
{
/// <summary>
/// 配置文件基类
/// </summary>
/// <typeparam name="TConfig">类型</typeparam>
public abstract class BaseConfig<TConfig> where TConfig : BaseConfig<TConfig>, new()
{
/// <summary>
/// 实体对象
/// </summary>
protected static TConfig current;
/// <summary>
/// 配置文件描述
/// </summary>
public static string Description
{
get
{
var fileanddesc = ConfigHelper.GetConfigFile<TConfig>();
return fileanddesc.Item2;
}
}
/// <summary>
/// 配置文件名
/// </summary>
public static string ConfigFile
{
get
{
var fileanddesc = ConfigHelper.GetConfigFile<TConfig>();
return fileanddesc.Item1;
}
}
/// <summary>
/// 当前可执行文件路径,末尾包括\
/// </summary>
/// <returns>结果</returns>
private static string CurrentDir()
{
return Environment.CurrentDirectory.DealPath();
}
/// <summary>
/// 当前实例。通过置空可以使其重新加载。
/// </summary>
public static TConfig Current
{
get
{
if (current != null)
{
return current;
}
// 现在没有对象尝试加载若返回null则实例化一个新的
current = CreateNew();
if (!current.Load(CurrentDir() + ConfigFile))
{
try
{
// 根据配置,有可能不保存,直接返回默认
current.Save();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return current;
}
set => current = value;
}
private static TConfig CreateNew()
{
TConfig config = new TConfig();
config.SetDefault();
return config;
}
/// <summary>保存到配置文件中去</summary>
public void Save()
{
Save(null);
}
/// <summary>
/// 加载指定配置文件
/// </summary>
/// <returns>结果</returns>
public bool Load()
{
return Load(null);
}
/// <summary>
/// 加密
/// </summary>
/// <param name="str">字符串</param>
/// <returns>加密后字符串</returns>
public string Encrypt(string str)
{
Random random = new Random();
var value = random.Next(100000, 999999);
string tmp = str + value.ToString();
return tmp.DesEncrypt();
}
/// <summary>
/// 解密
/// </summary>
/// <param name="str">字符串</param>
/// <returns>解密后字符串</returns>
public string Decrypt(string str)
{
string result = str.DesDecrypt();
return result.Left(result.Length - 6);
}
/// <summary>加载指定配置文件</summary>
/// <param name="filename">文件名</param>
/// <returns>结果</returns>
public abstract bool Load(string filename);
/// <summary>保存到配置文件中去</summary>
/// <param name="filename">文件名</param>
public abstract void Save(string filename);
/// <summary>
/// 设置默认值
/// </summary>
public virtual void SetDefault()
{
}
}
/// <summary>
/// 忽略此属性的配置存储
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class MapperIgnoreAttribute : Attribute
{
}
/// <summary>
/// 忽略此属性的配置存储
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class IgnoreAttribute : Attribute
{
}
/// <summary>
/// 配置文件帮助类
/// </summary>
public static class ConfigHelper
{
/// <summary>
/// 类型是否能够转为指定基类
/// </summary>
/// <param name="type">类型</param>
/// <param name="baseType">基类</param>
/// <returns>是否能够转为指定基类</returns>
public static bool As(this Type type, Type baseType)
{
if (type == null)
{
return false;
}
// 如果基类是泛型定义
if (baseType.IsGenericTypeDefinition && type.IsGenericType && !type.IsGenericTypeDefinition)
{
type = type.GetGenericTypeDefinition();
}
if (type == baseType)
{
return true;
}
if (baseType.IsAssignableFrom(type))
{
return true;
}
var rs = false;
// 接口
if (baseType.IsInterface)
{
if (type.GetInterface(baseType.FullName) != null)
{
rs = true;
}
else
foreach (var e in type.GetInterfaces())
{
if (e.IsGenericType && baseType.IsGenericTypeDefinition ? e.GetGenericTypeDefinition() == baseType : e == baseType)
{
rs = true;
break;
}
}
}
// 判断是否子类时,支持只反射加载的程序集
if (!rs && type.Assembly.ReflectionOnly)
{
// 反射加载时,需要特殊处理接口
while (!rs && type != typeof(object))
{
if (type == null)
{
continue;
}
if (type.FullName == baseType.FullName && type.AssemblyQualifiedName == baseType.AssemblyQualifiedName)
{
rs = true;
}
type = type.BaseType;
}
}
return rs;
}
/// <summary>是否泛型字典</summary>
/// <param name="type">类型</param>
/// <returns>是否泛型字典</returns>
public static bool IsDictionary(this Type type) => type != null && type.IsGenericType && type.As(typeof(IDictionary<,>));
/// <summary>是否泛型列表</summary>
/// <param name="type">类型</param>
/// <returns>是否泛型列表</returns>
public static bool IsList(this Type type)
{
return type != null && type.IsGenericType && type.As(typeof(IList<>));
//return Array.IndexOf(type.GetInterfaces(), typeof(IEnumerable)) > -1;
}
/// <summary>获取成员绑定的显示名优先DisplayName然后Description</summary>
/// <param name="member">member</param>
/// <returns>显示名</returns>
public static string DisplayName(this PropertyInfo member)
{
var att = member.GetCustomAttribute<DisplayNameAttribute>();
if (att != null && !att.DisplayName.IsNullOrWhiteSpace())
{
return att.DisplayName;
}
return "";
}
/// <summary>获取成员绑定的显示名优先DisplayName然后Description</summary>
/// <param name="member">member</param>
/// <returns>显示名</returns>
public static string Description(this PropertyInfo member)
{
var att2 = member.GetCustomAttribute<DescriptionAttribute>();
if (att2 != null && !att2.Description.IsNullOrWhiteSpace())
{
return att2.Description;
}
return "";
}
/// <summary>
/// 获取需要的属性,删除忽略的属性
/// </summary>
/// <param name="type">类型</param>
/// <returns>属性列表</returns>
public static List<PropertyInfo> GetNeedProperties(this Type type)
{
var list = type.GetProperties();
List<PropertyInfo> result = new List<PropertyInfo>();
foreach (var info in list)
{
if (info.GetCustomAttribute<XmlIgnoreAttribute>() != null)
{
continue;
}
if (info.GetCustomAttribute<ConfigIgnoreAttribute>() != null)
{
continue;
}
if (info.GetCustomAttribute<MapperIgnoreAttribute>() != null)
{
continue;
}
if (info.GetCustomAttribute<IgnoreAttribute>() != null)
{
continue;
}
result.Add(info);
}
return result;
}
/// <summary>
/// 获取配置文件路径
/// </summary>
/// <typeparam name="TConfig">类型</typeparam>
/// <returns>文件名</returns>
public static Tuple<string, string> GetConfigFile<TConfig>()
{
string filename;
string description = "配置文件";
var att = typeof(TConfig).GetCustomAttribute<ConfigFileAttribute>();
if (att == null || att.FileName.IsNullOrWhiteSpace())
{
filename = $"{typeof(TConfig).Name}.cfg";
}
else
{
filename = att.FileName;
if (!att.Description.IsNullOrEmpty())
{
description = att.Description;
}
}
return new Tuple<string, string>(filename, description);
}
/// <summary>
/// 初始化属性
/// </summary>
/// <param name="config">配置类</param>
/// <typeparam name="TConfig">类型</typeparam>
/// <returns>节点</returns>
/// <exception cref="ApplicationException">ApplicationException</exception>
public static ConcurrentDictionary<string, Ident> InitIdents<TConfig>(TConfig config)
{
ConcurrentDictionary<string, Ident> idents = new ConcurrentDictionary<string, Ident>();
var list = config.GetType().GetNeedProperties();
foreach (PropertyInfo info in list)
{
Ident ident = new Ident
{
Key = info.Name,
Show = true,
Description = info.Description(),
IsList = info.PropertyType.IsList()
};
var section = info.GetCustomAttribute<ConfigSectionAttribute>();
ident.Section = section != null ? section.Section : "";
var propertyatt = info.GetCustomAttribute<ConfigPropertyAttribute>();
ident.Caption = propertyatt != null ? propertyatt.Caption : "";
ident.Unit = propertyatt != null ? propertyatt.Unit : "";
ident.Description = propertyatt != null ? propertyatt.Description : "";
var indexatt = info.GetCustomAttribute<ConfigIndexAttribute>();
ident.Index = indexatt?.Index ?? short.MaxValue + idents.Count;
ident.Show = indexatt == null || indexatt.Show;
if (ident.Description.IsNullOrEmpty())
{
ident.Description = info.DisplayName() ?? info.Description();
}
if (ident.Description.IsNullOrEmpty())
{
ident.Description = "";
}
if (!idents.ContainsKey(ident.Key))
{
idents.TryAdd(ident.Key, ident);
}
}
return idents;
}
/// <summary>
/// 类型默认值
/// </summary>
/// <param name="targetType">类型</param>
/// <returns>默认值</returns>
public static object DefaultValue(Type targetType)
{
return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
}
/// <summary>
/// 读取对象数值
/// </summary>
/// <param name="config">配置文件</param>
/// <param name="idents">节点</param>
/// <typeparam name="TConfig">类型</typeparam>
/// <exception cref="ApplicationException">ApplicationException</exception>
public static void LoadConfigValue<TConfig>(TConfig config, ConcurrentDictionary<string, Ident> idents)
{
var list = config.GetType().GetNeedProperties();
foreach (PropertyInfo info in list)
{
object defaultobj = info.GetValue(config, null);
Type type = info.PropertyType;
if (type == typeof(string))
{
object value = idents[info.Name].Value;
info.SetValue(config, Convert.ChangeType(value == null ? defaultobj : value, type), null);
continue;
}
if (ConvertEx.CanConvent(type))
{
object value = ConvertEx.StringToObject(idents[info.Name].Value, type, defaultobj);
info.SetValue(config, Convert.ChangeType(value, type), null);
continue;
}
if (type.IsList())
{
Type[] genericTypes = type.GetGenericArguments();
if (genericTypes.Length != 1)
{
throw new ApplicationException("转换出错: " + type.FullName);
}
Type childtype = genericTypes[0];
Type typeDataList = typeof(List<>).MakeGenericType(childtype);
MethodInfo methodInfo = typeDataList.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);
if (methodInfo == null)
{
continue;
}
object listvalue = typeDataList.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, new object[] { });
foreach (string strvalue in idents[info.Name].Values)
{
if (childtype == typeof(string))
{
object value = strvalue;
methodInfo.Invoke(listvalue, new[] { value });
}
else if (ConvertEx.CanConvent(childtype))
{
object value = ConvertEx.StringToObject(strvalue, childtype, DefaultValue(childtype));
methodInfo.Invoke(listvalue, new[] { value });
}
}
info.SetValue(config, listvalue, null);
continue;
}
throw new ApplicationException("不支持此类型: " + type.FullName);
}
}
/// <summary>
/// 设置对象数值
/// </summary>
/// <param name="config">配置文件</param>
/// <param name="idents">节点</param>
/// <typeparam name="TConfig">类型</typeparam>
/// <exception cref="ApplicationException">ApplicationException</exception>
public static void SaveConfigValue<TConfig>(TConfig config, ConcurrentDictionary<string, Ident> idents)
{
var list = config.GetType().GetNeedProperties();
foreach (PropertyInfo info in list)
{
object obj = info.GetValue(config, null);
Type type = info.PropertyType;
if (ConvertEx.CanConvent(type))
{
string value = ConvertEx.ObjectToString(obj, type);
idents[info.Name].Value = value;
continue;
}
if (type.IsList())
{
Type[] genericTypes = type.GetGenericArguments();
if (genericTypes.Length != 1)
{
throw new ApplicationException("转换出错: " + type.FullName);
}
Type childtype = genericTypes[0];
IEnumerable en = obj as IEnumerable;
if (en == null)
{
throw new ApplicationException("转换出错: " + type.FullName);
}
idents[info.Name].Values.Clear();
foreach (object child in en)
{
if (ConvertEx.CanConvent(childtype))
{
idents[info.Name].Values.Add(ConvertEx.ObjectToString(child, childtype));
}
else
{
throw new ApplicationException("不支持此类型: " + type.FullName);
}
}
continue;
}
throw new ApplicationException("不支持此类型: " + type.FullName);
}
}
}
/// <summary>配置文件特性</summary>
[AttributeUsage(AttributeTargets.Class)]
public class ConfigFileAttribute : Attribute
{
/// <summary>
/// 配置文件名
/// </summary>
public string FileName { get; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; }
/// <summary>
/// 配置文件
/// </summary>
public ConfigFileAttribute() : this(string.Empty, string.Empty)
{
}
/// <summary>配置文件</summary>
/// <param name="fileName">文件名</param>
/// <param name="description">描述</param>
public ConfigFileAttribute(string fileName, string description = "")
{
FileName = fileName;
Description = description;
}
}
/// <summary>
/// 数据节点
/// </summary>
public class Ident
{
/// <summary>
/// 节
/// </summary>
public string Section { get; set; }
/// <summary>
/// 键
/// </summary>
public string Key { get; set; }
/// <summary>
/// 值
/// </summary>
public string Value { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Caption { get; set; }
/// <summary>
/// 单位
/// </summary>
public string Unit { get; set; }
/// <summary>
/// 序号
/// </summary>
public int Index { get; set; }
/// <summary>
/// 是否显示
/// </summary>
public bool Show { get; set; }
/// <summary>
/// ToString()
/// </summary>
/// <returns>String</returns>
public override string ToString()
{
return Index + " [" + Section + "] " + Key + " = ?";
}
/// <summary>
/// 是否是列表类型
/// </summary>
public bool IsList { get; set; }
/// <summary>
/// 列表值
/// </summary>
public List<string> Values = new List<string>();
}
/// <summary>
/// 配置属性节点特性
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ConfigSectionAttribute : Attribute
{
/// <summary>
/// 节
/// </summary>
public string Section { get; }
/// <summary>属性节点特性</summary>
/// <param name="section">节</param>
public ConfigSectionAttribute(string section)
{
Section = section;
}
}
/// <summary>
/// 配置属性描述特性
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ConfigPropertyAttribute : Attribute
{
/// <summary>
/// 标题
/// </summary>
public string Caption { get; }
/// <summary>
/// 单位
/// </summary>
public string Unit { get; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; }
/// <summary>
/// 配置文件属性
/// </summary>
/// <param name="caption">标题</param>
/// <param name="unit">单位</param>
/// <param name="description">描述</param>
public ConfigPropertyAttribute(string caption, string description = "", string unit = "")
{
Caption = caption;
Unit = unit;
Description = description;
}
}
/// <summary>
/// 忽略此属性的配置存储
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ConfigIgnoreAttribute : Attribute
{
}
/// <summary>
/// 配置序号描述特性
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ConfigIndexAttribute : Attribute
{
/// <summary>
/// 序号
/// </summary>
public int Index { get; }
/// <summary>
/// 是否显示
/// </summary>
public bool Show { get; }
/// <summary>配置序号特性</summary>
/// <param name="index">序号</param>
/// <param name="show">是否显示</param>
public ConfigIndexAttribute(int index, bool show = true)
{
Index = index;
Show = show;
}
}
}

View File

@ -0,0 +1,371 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2023 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.Common.dll can be used for free under the MIT license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UConvertEx.cs
* :
* : V3.1
* : 2020-01-01
*
* 2020-11-20: V3.0.0
******************************************************************************/
using System;
using System.Drawing;
namespace Sunny.UI
{
/// <summary>
/// 对象转换扩展类
/// </summary>
public static class ConvertEx
{
/// <summary>
/// 可以对象和字符串互相转换的类型
/// </summary>
/// <param name="type">类型</param>
/// <returns>结果</returns>
public static bool CanConvent(Type type)
{
bool result = false;
TypeCode typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.String:
case TypeCode.Char:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
case TypeCode.Boolean:
case TypeCode.DateTime:
result = true;
break;
case TypeCode.Object:
if (type == typeof(Point) ||
type == typeof(PointF) ||
type == typeof(Color) ||
type == typeof(Size) ||
type == typeof(SizeF))
{
result = true;
}
break;
}
return result;
}
/// <summary>
/// 字符串转对象
/// </summary>
/// <param name="str">字符串</param>
/// <param name="type">类型</param>
/// <param name="defaultobj">默认对象</param>
/// <returns>对象</returns>
public static object StringToObject(string str, Type type, object defaultobj)
{
object obj = defaultobj;
if (type == typeof(string))
{
return str;
}
if (str.IsNullOrEmpty())
{
return defaultobj;
}
TypeCode typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.Char:
obj = str.ToChar((char)defaultobj);
break;
case TypeCode.SByte:
obj = str.ToSByte((sbyte)defaultobj);
break;
case TypeCode.Byte:
obj = str.ToByte((byte)defaultobj);
break;
case TypeCode.Int16:
obj = str.ToShort((short)defaultobj);
break;
case TypeCode.UInt16:
obj = str.ToUShort((ushort)defaultobj);
break;
case TypeCode.Int32:
obj = str.ToInt((int)defaultobj);
break;
case TypeCode.UInt32:
obj = str.ToUInt((uint)defaultobj);
break;
case TypeCode.Int64:
obj = str.ToLong((long)defaultobj);
break;
case TypeCode.UInt64:
obj = str.ToULong((ulong)defaultobj);
break;
case TypeCode.Single:
obj = str.ToFloat((float)defaultobj);
break;
case TypeCode.Double:
obj = str.ToDouble((double)defaultobj);
break;
case TypeCode.Decimal:
obj = str.ToDecimal((decimal)defaultobj);
break;
case TypeCode.Boolean:
if (str.ToUpper().Equals(bool.TrueString.ToUpper()))
{
obj = true;
}
if (str.ToUpper().Equals(bool.FalseString.ToUpper()))
{
obj = false;
}
break;
case TypeCode.DateTime:
try
{
DateTime dt = str.ToDateTime(DateTimeEx.DateTimeFormat);
obj = dt;
}
catch (Exception e)
{
Console.WriteLine(e);
}
break;
case TypeCode.Object:
obj = StringToObjectEx(str, type, defaultobj);
break;
default:
throw new ApplicationException("不支持此类型: " + type.FullName);
}
if (type == typeof(DateTime))
{
}
return obj;
}
/// <summary>
/// 字符串转对象扩展
/// </summary>
/// <param name="str">字符串</param>
/// <param name="type">类型</param>
/// <param name="defaultobj">默认对象</param>
/// <returns>对象</returns>
private static object StringToObjectEx(string str, Type type, object defaultobj)
{
object obj = defaultobj;
if (type == typeof(Point))
{
string[] strs = str.ToUpper().Replace("X:", "").Replace("Y:", "").Trim().Split(";");
if (strs.Length == 2)
{
if (int.TryParse(strs[0], out var x) && int.TryParse(strs[1], out var y))
{
obj = new Point(x, y);
}
}
}
else if (type == typeof(PointF))
{
string[] strs = str.ToUpper().Replace("X:", "").Replace("Y:", "").Trim().Split(";");
if (strs.Length == 2)
{
if (float.TryParse(strs[0], out var x) && float.TryParse(strs[1], out var y))
{
obj = new PointF(x, y);
}
}
}
else if (type == typeof(Color))
{
string[] strs = str.ToUpper().Replace("A:", "").Replace("R:", "").Replace("G:", "").Replace("B:", "").Trim().Split(";");
if (strs.Length == 4)
{
if (int.TryParse(strs[0], out var a) && int.TryParse(strs[1], out var r) && int.TryParse(strs[2], out var g) && int.TryParse(strs[3], out var b))
{
if (a.InRange(0, 255) && r.InRange(0, 255) && g.InRange(0, 255) && b.InRange(0, 255))
{
obj = Color.FromArgb(a, r, g, b);
}
}
}
}
else if (type == typeof(Size))
{
string[] strs = str.ToUpper().Replace("W:", "").Replace("H:", "").Trim().Split(";");
if (strs.Length == 2)
{
if (int.TryParse(strs[0], out var x) && int.TryParse(strs[1], out var y))
{
obj = new Size(x, y);
}
}
}
else if (type == typeof(SizeF))
{
string[] strs = str.ToUpper().Replace("W:", "").Replace("H:", "").Trim().Split(";");
if (strs.Length == 2)
{
if (float.TryParse(strs[0], out var x) && float.TryParse(strs[1], out var y))
{
obj = new SizeF(x, y);
}
}
}
else
{
throw new ApplicationException("不支持此类型: " + type.FullName);
}
return obj;
}
/// <summary>
/// 对象转字符串
/// </summary>
/// <param name="obj">对象</param>
/// <param name="type">类型</param>
/// <returns>字符串</returns>
public static string ObjectToString(object obj, Type type)
{
string value;
TypeCode typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.String:
if (obj == null)
{
obj = "";
}
value = obj.ToString();
break;
case TypeCode.Char:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
value = obj.ToString();
break;
case TypeCode.Boolean:
value = (bool)obj ? bool.TrueString : bool.FalseString;
break;
case TypeCode.DateTime:
value = ((DateTime)obj).ToString(DateTimeEx.DateTimeFormat);
break;
case TypeCode.Object:
value = ObjectToStringEx(obj, type);
break;
default:
throw new ApplicationException("不支持此类型: " + type.FullName);
}
return value;
}
/// <summary>
/// 对象转字符串扩展
/// </summary>
/// <param name="obj">对象</param>
/// <param name="type">类型</param>
/// <returns>字符串</returns>
private static string ObjectToStringEx(object obj, Type type)
{
string value;
if (type == typeof(Point))
{
Point point = (Point)obj;
value = "X:" + point.X + "; Y:" + point.Y;
}
else if (type == typeof(PointF))
{
PointF point = (PointF)obj;
value = "X:" + point.X + "; Y:" + point.Y;
}
else if (type == typeof(Color))
{
Color color = (Color)obj;
value = "A:" + color.A + "; R:" + color.R + "; G:" + color.G + "; B:" + color.B;
}
else if (type == typeof(Size))
{
Size size = (Size)obj;
value = "W:" + size.Width + "; H:" + size.Height;
}
else if (type == typeof(SizeF))
{
SizeF size = (SizeF)obj;
value = "W:" + size.Width + "; H:" + size.Height;
}
else
{
throw new ApplicationException("不支持此类型: " + type.FullName);
}
return value;
}
}
}

View File

@ -0,0 +1,382 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2023 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UDateTimeInt64.cs
* :
* : V2.2
* : 2020-09-23
*
* 2020-09-23: V2.2.8
* 2020-10-10: V2.2.8 Double互转
******************************************************************************/
using System;
namespace Sunny.UI
{
/// <summary>
/// 日期与长整形和浮点型互转
/// Value长整形为1970年1月1日0时起的毫秒数
/// DoubleValue双精度浮点数1970年1月1日0时起的天数
/// </summary>
public struct DateTimeInt64 : IComparable, IEquatable<DateTimeInt64>, IEquatable<long>, IEquatable<DateTime>
{
public long Value { get; set; }
public const long Jan1st1970Ticks = 621355968000000000; //Jan1st1970.Ticks;
public const long Dec31th9999Ticks = 3155378975999990000; //DateTime.MaxValue.Ticks;
public const string DefaultFormatString = DateTimeEx.DateTimeFormatEx;
public const double MillisecondsPerDay = 86400000.0;
/// <summary>
/// 返回当前时间的毫秒数, 这个毫秒其实就是自1970年1月1日0时起的毫秒数
/// </summary>
public static long CurrentDateTimeToTicks()
{
return (DateTime.UtcNow.Ticks - Jan1st1970Ticks) / 10000;
}
public double DoubleValue
{
get { return Value * 1.0 / MillisecondsPerDay; }
set { Value = (long)(value * MillisecondsPerDay); }
}
/// <summary>
/// 返回指定时间的毫秒数, 这个毫秒其实就是自1970年1月1日0时起的毫秒数
/// </summary>
public static long DateTimeToTicks(DateTime datetime)
{
return (datetime.ToUniversalTime().Ticks - Jan1st1970Ticks) / 10000;
}
/// <summary>
/// 从一个代表自1970年1月1日0时起的毫秒数转换为DateTime (北京时间)
/// </summary>
public static DateTime TicksToDateTime(long ticks)
{
#pragma warning disable CS0618 // 类型或成员已过时
return TimeZone.CurrentTimeZone.ToLocalTime(TicksToUTCDateTime(ticks));
#pragma warning restore CS0618 // 类型或成员已过时
}
/// <summary>
/// 从一个代表自1970年1月1日0时起的毫秒数转换为DateTime (UTC时间)
/// </summary>
public static DateTime TicksToUTCDateTime(long ticks)
{
return new DateTime(ticks * 10000 + Jan1st1970Ticks);
}
public DateTimeInt64(long ticks)
{
ticks = MakeValidDate(ticks);
Value = ticks;
}
public DateTimeInt64(double doubleTicks)
{
doubleTicks = MakeValidDate((long)(doubleTicks * MillisecondsPerDay));
Value = (long)doubleTicks;
}
public DateTimeInt64(DateTime dateTime)
{
Value = DateTimeToTicks(dateTime);
}
public DateTimeInt64(int year, int month, int day)
{
Value = DateTimeToTicks(new DateTime(year, month, day));
}
public DateTimeInt64(int year, int month, int day, int hour, int minute, int second)
{
Value = DateTimeToTicks(new DateTime(year, month, day, hour, minute, second));
}
public DateTimeInt64(int year, int month, int day, int hour, int minute, int second, int millisecond)
{
Value = DateTimeToTicks(new DateTime(year, month, day, hour, minute, second, millisecond));
}
public DateTimeInt64(DateTimeInt64 dtValue)
{
Value = dtValue.Value;
}
public bool IsValidDate
{
get { return Value >= 0 && Value <= Dec31th9999Ticks - Jan1st1970Ticks; }
}
public DateTime DateTime
{
get { return TicksToDateTime(Value); }
set { Value = DateTimeToTicks(value); }
}
public static bool CheckValidDate(long ticks)
{
return ticks >= 0 && ticks <= Dec31th9999Ticks - Jan1st1970Ticks;
}
public static long MakeValidDate(long ticks)
{
if (ticks < 0)
ticks = 0;
if (ticks > Dec31th9999Ticks - Jan1st1970Ticks)
ticks = Dec31th9999Ticks - Jan1st1970Ticks;
return ticks;
}
public void AddMilliseconds(double milliseconds)
{
Value = DateTimeToTicks(DateTime.AddMilliseconds(milliseconds));
}
public void AddSeconds(double seconds)
{
Value = DateTimeToTicks(DateTime.AddSeconds(seconds));
}
public void AddMinutes(double minutes)
{
Value = DateTimeToTicks(DateTime.AddMinutes(minutes));
}
public void AddHours(double hours)
{
Value = DateTimeToTicks(DateTime.AddHours(hours));
}
public void AddDays(double days)
{
Value = DateTimeToTicks(DateTime.AddDays(days));
}
public void AddMonths(int months)
{
Value = DateTimeToTicks(DateTime.AddMonths(months));
}
public void AddYears(int years)
{
Value = DateTimeToTicks(DateTime.AddYears(years));
}
public static long operator -(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value - dtValue2.Value;
}
public static long operator +(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value + dtValue2.Value;
}
public static DateTimeInt64 operator -(DateTimeInt64 dtValue1, long dtValue2)
{
dtValue1.Value -= dtValue2;
return dtValue1;
}
public static DateTimeInt64 operator +(DateTimeInt64 dtValue1, long dtValue2)
{
dtValue1.Value += dtValue2;
return dtValue1;
}
public static DateTimeInt64 operator ++(DateTimeInt64 dtValue)
{
dtValue.AddDays(1);
return dtValue;
}
public static DateTimeInt64 operator --(DateTimeInt64 dtValue)
{
dtValue.AddDays(-1);
return dtValue;
}
public static implicit operator long(DateTimeInt64 dtValue)
{
return dtValue.Value;
}
public static implicit operator DateTimeInt64(long ticks)
{
return new DateTimeInt64(ticks);
}
public static implicit operator DateTimeInt64(DateTime dt)
{
return new DateTimeInt64(dt);
}
public static implicit operator DateTime(DateTimeInt64 dt)
{
return dt.DateTime;
}
public static implicit operator double(DateTimeInt64 dtValue)
{
return dtValue.DoubleValue;
}
public static implicit operator DateTimeInt64(double ticks)
{
return new DateTimeInt64(ticks);
}
public static bool operator ==(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value == dtValue2.Value;
}
public static bool operator !=(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value != dtValue2.Value;
}
public static bool operator ==(DateTimeInt64 dtValue, long ticks)
{
return dtValue.Value == ticks;
}
public static bool operator !=(DateTimeInt64 dtValue, long ticks)
{
return dtValue.Value != ticks;
}
public static bool operator <(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value < dtValue2.Value;
}
public static bool operator >(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value > dtValue2.Value;
}
public static bool operator <=(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value <= dtValue2.Value;
}
public static bool operator >=(DateTimeInt64 dtValue1, DateTimeInt64 dtValue2)
{
return dtValue1.Value >= dtValue2.Value;
}
public static bool operator <(DateTimeInt64 dtValue, long ticks)
{
return dtValue.Value < ticks;
}
public static bool operator >(DateTimeInt64 dtValue, long ticks)
{
return dtValue.Value > ticks;
}
public static bool operator <=(DateTimeInt64 dtValue, long ticks)
{
return dtValue.Value <= ticks;
}
public static bool operator >=(DateTimeInt64 dtValue, long ticks)
{
return dtValue.Value >= ticks;
}
public override bool Equals(object obj)
{
if (obj is DateTimeInt64 dtValue)
{
return dtValue.Value == Value;
}
else if (obj is long longValue)
{
return longValue == Value;
}
else
{
return false;
}
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
int IComparable.CompareTo(object obj)
{
if (!(obj is DateTimeInt64)) throw new ArgumentException();
return (Value).CompareTo(((DateTimeInt64)obj).Value);
}
public string ToString(long ticks)
{
return ToString(ticks, DefaultFormatString);
}
public override string ToString()
{
return ToString(Value, DefaultFormatString);
}
public string ToString(string fmtStr)
{
return ToString(Value, fmtStr);
}
public static string ToString(long dtValue, string fmtStr)
{
DateTime dt = TicksToDateTime(dtValue);
return dt.ToString(fmtStr);
}
public bool Equals(DateTimeInt64 dtValue)
{
return Value == dtValue.Value;
}
public bool Equals(long ticks)
{
return Value == ticks;
}
public bool Equals(DateTime datetime)
{
return Value == (new DateTimeInt64(datetime)).Value;
}
public string DateTimeString => DateTime.DateTimeString();
public string DateString => DateTime.DateString();
public string TimeString => DateTime.TimeString();
public string HourMinuteString => DateTime.ToString("HH:mm");
public int Year => DateTime.Year;
public int Month => DateTime.Month;
public int Day => DateTime.Day;
public int Hour => DateTime.Hour;
public int Minute => DateTime.Minute;
public int Second => DateTime.Second;
public int Millisecond => DateTime.Millisecond;
}
}

View File

@ -22,7 +22,6 @@
* 2023-08-11: v3.4.1
******************************************************************************/
using Sunny.UI.Win32;
using System;
using System.Collections.Specialized;
using System.ComponentModel;
@ -31,6 +30,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Sunny.UI.Win32;
namespace Sunny.UI
{
@ -299,29 +299,6 @@ namespace Sunny.UI
/// </summary>
public class IniFile : IniBase
{
/// <summary>
/// 写Byte数组
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, byte[] value)
{
Write(section, key, value.ToHexString());
}
/// <summary>
/// 读Byte数组
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public byte[] ReadBytes(string section, string key, byte[] Default)
{
return Read(section, key, Default.ToHexString()).ToHexBytes();
}
/// <summary>
/// 写Char
/// </summary>

View File

@ -0,0 +1,790 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2023 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UIniFileEx.cs
* : INI WinAPI
* : V3.1
* : 2021-10-27
*
* 2021-10-27: V2.2.0
******************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace Sunny.UI
{
public class IniFileEx
{
private readonly Dictionary<string, NameValueCollection> data = new Dictionary<string, NameValueCollection>();
private static readonly Regex regRemoveEmptyLines =
new Regex
(
@"(\s*;[\d\D]*?\r?\n)+|\r?\n(\s*\r?\n)*",
RegexOptions.Multiline | RegexOptions.Compiled
);
private static readonly Regex regParseIniData =
new Regex
(
@"
(?<IsSection>
^\s*\[(?<SectionName>[^\]]+)?\]\s*$
)
|
(?<IsKeyValue>
^\s*(?<Key>[^(\s*\=\s*)]+)?\s*\=\s*(?<Value>[\d\D]*)$
)",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace
);
public IniFileEx(string fileName) : this(fileName, Encoding.Default) { }
public IniFileEx(string fileName, Encoding encoding)
{
FileName = fileName;
Encoding = encoding;
using FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
ReadIniData(fs, encoding);
}
/// <summary>
/// 文件名
/// </summary>
[Description("文件名")]
public string FileName { get; set; } //INI文件名
public Encoding Encoding { get; set; }
private void ReadIniData(Stream stream, Encoding encoding)
{
string lastSection = string.Empty;
data.Add(lastSection, new NameValueCollection());
if (stream != null && encoding != null)
{
using StreamReader reader = new StreamReader(stream, encoding);
string iniData = reader.ReadToEnd();
iniData = regRemoveEmptyLines.Replace(iniData, "\n");
string[] lines = iniData.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in lines)
{
Match m = regParseIniData.Match(s);
if (m.Success)
{
if (m.Groups["IsSection"].Length > 0)
{
string sName = m.Groups["SectionName"].Value.ToLowerInvariant();
if (lastSection != sName)
{
lastSection = sName;
if (!data.ContainsKey(sName))
{
data.Add(sName, new NameValueCollection());
}
}
}
else if (m.Groups["IsKeyValue"].Length > 0)
{
data[lastSection].Add(m.Groups["Key"].Value, m.Groups["Value"].Value);
}
}
}
}
}
public NameValueCollection this[string section]
{
get
{
section = section.ToLowerInvariant();
if (!data.ContainsKey(section))
data.Add(section, new NameValueCollection());
return data[section];
}
}
public string this[string section, string key]
{
get => this[section][key];
set => this[section][key] = value;
}
public object this[string section, string key, Type t]
{
get
{
if (t == null || t == (Type)Type.Missing)
return this[section][key];
return GetValue(section, key, null, t);
}
set
{
if (t == null || t == (Type)Type.Missing)
this[section][key] = string.Empty;
else
SetValue(section, key, value);
}
}
public string[] KeyNames(string section)
{
return this[section].AllKeys;
}
public string[] SectionValues(string section)
{
return this[section].GetValues(0);
}
private object GetValue(string section, string key, object defaultValue, Type t)
{
section = section.ToLowerInvariant();
key = key.ToLowerInvariant();
if (!data.ContainsKey(section)) return defaultValue;
string v = data[section][key];
if (string.IsNullOrEmpty(v)) return defaultValue;
TypeConverter conv = TypeDescriptor.GetConverter(t);
if (!conv.CanConvertFrom(typeof(string))) return defaultValue;
try
{
return conv.ConvertFrom(v);
}
catch
{
return defaultValue;
}
}
private T GetValue<T>(string section, string key, T defaultValue)
{
return (T)GetValue(section, key, defaultValue, typeof(T));
}
private void SetValue(string section, string key, object value)
{
if (value == null)
{
this[section][key] = string.Empty;
}
else
{
TypeConverter conv = TypeDescriptor.GetConverter(value);
if (!conv.CanConvertTo(typeof(string)))
{
this[section][key] = value.ToString();
}
else
{
this[section][key] = (string)conv.ConvertTo(value, typeof(string));
}
}
UpdateFile();
}
public void Write(string section, string key, string value)
{
SetValue(section, key, value);
}
public string Read(string section, string key, string Default)
{
return GetValue(section, key, Default);
}
/// <summary>
/// 读取指定的Section的所有Value到列表中
/// </summary>
/// <param name="section">section</param>
public NameValueCollection GetSectionValues(string section)
{
return this[section];
}
public void UpdateFile()
{
Save();
}
public void Save()
{
Save(FileName, Encoding);
}
public void Save(string fileName, Encoding encoding)
{
using FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
Save(fs, encoding);
}
private void Save(Stream stream, Encoding encoding)
{
using StreamWriter sw = new StreamWriter(stream, encoding);
foreach (var cur in data)
{
if (!string.IsNullOrEmpty(cur.Key))
{
sw.WriteLine("[{0}]", cur.Key);
}
NameValueCollection col = cur.Value;
foreach (string key in col.Keys)
{
if (!string.IsNullOrEmpty(key))
{
string value = col[key];
if (!string.IsNullOrEmpty(value))
sw.WriteLine("{0}={1}", key, value);
}
}
}
sw.Flush();
}
public bool HasSection(string section)
{
return data.ContainsKey(section.ToLowerInvariant());
}
public bool HasKey(string section, string key)
{
return
data.ContainsKey(section) &&
!string.IsNullOrEmpty(data[section][key]);
}
/// <summary>
/// 写结构
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
/// <typeparam name="T">T</typeparam>
public void WriteStruct<T>(string section, string key, T value) where T : struct
{
Write(section, key, value.ToBytes());
}
/// <summary>
/// 读结构
/// </summary>
/// <typeparam name="T">T</typeparam>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public T ReadStruct<T>(string section, string key, T Default) where T : struct
{
//得到结构体的大小
int size = StructEx.Size(Default);
byte[] bytes = Read(section, key, "").ToHexBytes();
return size > bytes.Length ? Default : bytes.ToStruct<T>();
}
/// <summary>
/// 写Byte数组
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, byte[] value)
{
Write(section, key, value.ToHexString());
}
/// <summary>
/// 读Byte数组
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public byte[] ReadBytes(string section, string key, byte[] Default)
{
return Read(section, key, Default.ToHexString()).ToHexBytes();
}
/// <summary>
/// 写Char
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, char value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读Char
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public char ReadChar(string section, string key, char Default = ' ')
{
return Read(section, key, Default.ToString()).ToChar(Default);
}
/// <summary>
/// 写Decimal
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, decimal value)
{
Write(section, key, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// 读Decimal
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public decimal ReadDecimal(string section, string key, decimal Default = 0)
{
return Read(section, key, Default.ToString(CultureInfo.InvariantCulture)).ToDecimal(Default);
}
/// <summary>
/// 写整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, short value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public short ReadShort(string section, string key, short Default = 0)
{
return Read(section, key, Default.ToString()).ToShort(Default);
}
/// <summary>
/// 写整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, ushort value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public ushort ReadUShort(string section, string key, ushort Default = 0)
{
return Read(section, key, Default.ToString()).ToUShort(Default);
}
/// <summary>
/// 写整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, int value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public int ReadInt(string section, string key, int Default = 0)
{
return Read(section, key, Default.ToString()).ToInt(Default);
}
/// <summary>
/// 写整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, uint value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public uint ReadUInt(string section, string key, uint Default = 0)
{
return Read(section, key, Default.ToString()).ToUInt(Default);
}
/// <summary>
/// 写整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, ulong value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public ulong ReadULong(string section, string key, ulong Default = 0)
{
return Read(section, key, Default.ToString()).ToULong(Default);
}
/// <summary>
/// 写整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, long value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读整数
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public long ReadLong(string section, string key, long Default = 0)
{
return Read(section, key, Default.ToString()).ToLong(Default);
}
/// <summary>
/// 写布尔
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, bool value)
{
Write(section, key, value ? bool.TrueString : bool.FalseString);
}
/// <summary>
/// 读布尔
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public bool ReadBool(string section, string key, bool Default = false)
{
string str = Read(section, key, Default.ToString());
if (string.Equals(str, bool.TrueString, StringComparison.CurrentCultureIgnoreCase))
{
return true;
}
if (string.Equals(str, bool.FalseString, StringComparison.CurrentCultureIgnoreCase))
{
return false;
}
return Default;
}
/// <summary>
/// 写Double
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, double value)
{
Write(section, key, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// 读Double
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public double ReadDouble(string section, string key, double Default = 0)
{
return Read(section, key, Default.ToString(CultureInfo.InvariantCulture)).ToDouble(Default);
}
/// <summary>
/// 写Float
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, float value)
{
Write(section, key, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// 读Float
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public float ReadFloat(string section, string key, float Default = 0)
{
return Read(section, key, Default.ToString(CultureInfo.InvariantCulture)).ToFloat(Default);
}
/// <summary>
/// 写Byte
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, byte value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读Byte
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public byte ReadByte(string section, string key, byte Default = 0)
{
return Read(section, key, Default.ToString()).ToByte(Default);
}
/// <summary>
/// 写SByte
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, sbyte value)
{
Write(section, key, value.ToString());
}
/// <summary>
/// 读Byte
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public sbyte ReadSByte(string section, string key, sbyte Default = 0)
{
return Read(section, key, Default.ToString()).ToSByte(Default);
}
/// <summary>
/// 写DateTime
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, DateTime value)
{
Write(section, key, value.ToString(DateTimeEx.DateTimeFormat));
}
/// <summary>
/// 读DateTime
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public DateTime ReadDateTime(string section, string key, DateTime Default)
{
string str = Read(section, key, Default.ToString(CultureInfo.InvariantCulture));
try
{
return str.ToDateTime(DateTimeEx.DateTimeFormat);
}
catch (Exception)
{
return Default;
}
}
/// <summary>
/// 写Point
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, Point value)
{
Write(section, key, ConvertEx.ObjectToString(value, typeof(Point)));
}
/// <summary>
/// 读Point
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public Point ReadPoint(string section, string key, Point Default)
{
string str = Read(section, key, "");
return (Point)ConvertEx.StringToObject(str, typeof(Point), Default);
}
/// <summary>
/// 写PointF
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, PointF value)
{
Write(section, key, ConvertEx.ObjectToString(value, typeof(PointF)));
}
/// <summary>
/// 读PointF
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public PointF ReadPointF(string section, string key, PointF Default)
{
string str = Read(section, key, "");
return (PointF)ConvertEx.StringToObject(str, typeof(PointF), Default);
}
/// <summary>
/// 写Size
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, Size value)
{
Write(section, key, ConvertEx.ObjectToString(value, typeof(Size)));
}
/// <summary>
/// 读Size
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public Size ReadSize(string section, string key, Size Default)
{
string str = Read(section, key, "");
return (Size)ConvertEx.StringToObject(str, typeof(Size), Default);
}
/// <summary>
/// 写SizeF
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, SizeF value)
{
Write(section, key, ConvertEx.ObjectToString(value, typeof(SizeF)));
}
/// <summary>
/// 读SizeF
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public SizeF ReadSizeF(string section, string key, SizeF Default)
{
string str = Read(section, key, "");
return (SizeF)ConvertEx.StringToObject(str, typeof(SizeF), Default);
}
/// <summary>
/// 写Color
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="value">value</param>
public void Write(string section, string key, Color value)
{
Write(section, key, ConvertEx.ObjectToString(value, typeof(Color)));
}
/// <summary>
/// 读Color
/// </summary>
/// <param name="section">section</param>
/// <param name="key">key</param>
/// <param name="Default">Normal</param>
/// <returns>结果</returns>
public Color ReadColor(string section, string key, Color Default)
{
string str = Read(section, key, "");
return (Color)ConvertEx.StringToObject(str, typeof(Color), Default);
}
}
}

203
SunnyUI/Common/UMapper.cs Normal file
View File

@ -0,0 +1,203 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2023 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UMapper.cs
* : StructList和数组
* : V3.1
* : 2021-09-30
*
* 2021-09-30: V3.0.7
******************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Sunny.UI
{
/// <summary>
/// 轻量级的对象映射框架
/// </summary>
public static class Mapper
{
private static void Execute<T1, T2>(T1 source, T2 dest)
where T1 : class, new()
where T2 : class, new()
{
if (source == null || dest == null)
{
return;
}
var listSource = source.GetType().GetNeedProperties().ToDictionary(prop => prop.Name);
var listDest = dest.GetType().GetNeedProperties().ToDictionary(prop => prop.Name);
foreach (var item in listDest)
{
if (listSource.NotContainsKey(item.Key)) continue;
var sourceInfo = listSource[item.Key];
Type sourceType = sourceInfo.PropertyType;
object sourceValue = sourceInfo.GetValue(source, null);
var destInfo = item.Value;
Type destType = item.Value.PropertyType;
if (!sourceType.Equals(destType)) continue;
if (sourceType.IsValueType)
{
//Console.WriteLine("ValueType: " + item.Key + ", " + sourceType.FullName);
destInfo.SetValue(dest, sourceValue, null);
}
else
{
if (sourceType == typeof(string))
{
//Console.WriteLine("String: " + item.Key + ", " + sourceType.FullName);
destInfo.SetValue(dest, sourceValue, null);
continue;
}
if (sourceType.IsList())
{
//Console.WriteLine("List: " + item.Key + ", " + sourceType.FullName);
Type[] sourceTypes = sourceType.GetGenericArguments();
Type[] destTypes = destType.GetGenericArguments();
if (sourceTypes.Length != 1) continue;
if (destTypes.Length != 1) continue;
if (!sourceTypes[0].Equals(destTypes[0])) continue;
if (sourceValue == null)
{
destInfo.SetValue(dest, null, null);
}
else
{
Type typeDataList = typeof(List<>).MakeGenericType(destTypes[0]);
MethodInfo AddInfo = typeDataList.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);
if (AddInfo == null) continue;
if (sourceTypes[0].IsValueType || sourceTypes[0] == typeof(string))
{
object listvalue = typeDataList.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, new object[] { });
IEnumerable sourceList = sourceValue as IEnumerable;
foreach (var listItem in sourceList)
{
AddInfo.Invoke(listvalue, new[] { listItem });
}
destInfo.SetValue(dest, listvalue, null);
}
else
{
//暂时不考虑
}
}
continue;
}
if (sourceType.IsArray)
{
//Console.WriteLine("Array: " + item.Key + ", " + sourceType.FullName);
if (sourceValue == null)
{
destInfo.SetValue(dest, null, null);
}
else
{
ICollection sourceList = sourceValue as ICollection;
Type type = sourceType.GetElementType();
var array = Array.CreateInstance(type, sourceList.Count);
int index = 0;
foreach (var listItem in sourceList)
{
array.SetValue(listItem, index++);
}
destInfo.SetValue(dest, array, null);
}
continue;
}
if (sourceType.IsDictionary())
{
continue;
}
//类没有无参构造函数的话,创建有问题
//if (sourceType.IsClass)
//{
// if (sourceValue == null)
// {
// destInfo.SetValue(dest, null, null);
// }
// else
// {
// object obj = Activator.CreateInstance(sourceType, null);
// obj.MapperFrom(sourceValue);
// destInfo.SetValue(dest, obj, null);
// }
//
// continue;
//}
}
}
}
/// <summary>
/// T1映射到T2
/// </summary>
/// <typeparam name="T1">T1</typeparam>
/// <typeparam name="T2">T2</typeparam>
/// <param name="source">源</param>
/// <param name="dest">目标</param>
public static void MapperTo<T1, T2>(this T1 source, T2 dest)
where T1 : class, new()
where T2 : class, new()
{
Execute(source, dest);
}
/// <summary>
/// T1从T2映射
/// </summary>
/// <typeparam name="T1">T1</typeparam>
/// <typeparam name="T2">T2</typeparam>
/// <param name="source">源</param>
/// <param name="dest">目标</param>
public static void MapperFrom<T1, T2>(this T1 dest, T2 source)
where T1 : class, new()
where T2 : class, new()
{
Execute(source, dest);
}
/// <summary>
/// 获取数组的类类型
/// </summary>
/// <param name="t">类型</param>
/// <returns>类类型</returns>
public static Type GetArrayElementType(this Type t)
{
if (!t.IsArray) return null;
string name = t.FullName.Replace("[]", string.Empty);
return t.Assembly.GetType(name);
}
}
}

View File

@ -22,9 +22,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
#pragma warning disable 1591
@ -32,7 +32,7 @@ namespace Sunny.UI
{
public class Thunder : IDisposable
{
private readonly Timer timer;
private readonly System.Windows.Forms.Timer timer;
private bool Exit;
public delegate void OnTaskInfoChange(object sender, ThunderTask task);
@ -52,7 +52,7 @@ namespace Sunny.UI
public Thunder()
{
InitSuccess = ThunderDll.Init();
timer = new Timer();
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += Timer_Tick;
timer.Start();
@ -512,7 +512,7 @@ namespace Sunny.UI
public override string ToString()
{
return Status.DisplayText() + ",已完成:" + (Percent * 100.0f).ToString("F2") + "%,速度:" + Speed + "KB/s";
return Status.Description() + ",已完成:" + (Percent * 100.0f).ToString("F2") + "%,速度:" + Speed + "KB/s";
}
}
@ -524,43 +524,43 @@ namespace Sunny.UI
/// <summary>
/// 无
/// </summary>
[DisplayText("无")]
[Description("无")]
NOITEM = 0,
/// <summary>
/// 错误
/// </summary>
[DisplayText("错误")]
[Description("错误")]
TSC_ERROR,
/// <summary>
/// 暂停
/// </summary>
[DisplayText("暂停")]
[Description("暂停")]
TSC_PAUSE,
/// <summary>
/// 下载
/// </summary>
[DisplayText("下载中")]
[Description("下载中")]
TSC_DOWNLOAD,
/// <summary>
/// 完成
/// </summary>
[DisplayText("完成")]
[Description("完成")]
TSC_COMPLETE,
/// <summary>
/// 停止开始
/// </summary>
[DisplayText("已开始")]
[Description("已开始")]
TSC_STARTENDING,
/// <summary>
/// 停止完成
/// </summary>
[DisplayText("已停止")]
[Description("已停止")]
TSC_STOPENDING
}

View File

@ -0,0 +1,163 @@
/******************************************************************************
* SunnyUI
* CopyRight (C) 2012-2023 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.Common.dll can be used for free under the MIT license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UXmlConfig.cs
* : XML
* : V3.1
* : 2020-01-01
*
* 2020-01-01: V2.2.0
******************************************************************************/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
namespace Sunny.UI
{
/// <summary>
/// XML 配置文件类
/// </summary>
/// <typeparam name="TConfig">类型</typeparam>
public class XmlConfig<TConfig> : BaseConfig<TConfig> where TConfig : XmlConfig<TConfig>, new()
{
#region
/// <summary>
/// 当前可执行文件路径,末尾包括\
/// </summary>
/// <returns>结果</returns>
private static string CurrentDir()
{
return Environment.CurrentDirectory.DealPath();
}
/// <summary>加载指定配置文件</summary>
/// <param name="filename">文件名</param>
/// <returns>结果</returns>
public override bool Load(string filename)
{
if (filename.IsNullOrWhiteSpace())
{
filename = CurrentDir() + ConfigFile;
}
if (filename.IsNullOrWhiteSpace())
{
throw new ApplicationException($"未指定{typeof(TConfig).Name}的配置文件路径!");
}
if (!File.Exists(filename))
{
return false;
}
try
{
ConcurrentDictionary<string, Ident> idents = ConfigHelper.InitIdents(current);
XmlDocument doc = new XmlDocument();
doc.Load(filename);
XmlElement root = doc.DocumentElement; //获取根节点
foreach (Ident ident in idents.Values)
{
if (root != null)
{
var elements = root.GetElementsByTagName(ident.Key);
if (elements.Count == 1)
{
if (ident.IsList)
{
ident.Values.Clear();
foreach (XmlNode node in elements[0].ChildNodes)
{
ident.Values.Add(node.InnerText);
}
}
else
{
ident.Value = elements[0].InnerText;
}
}
}
}
ConfigHelper.LoadConfigValue(current, idents);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
/// <summary>保存到配置文件中去</summary>
/// <param name="filename">文件名</param>
public override void Save(string filename)
{
if (filename.IsNullOrWhiteSpace())
{
filename = CurrentDir() + ConfigFile;
}
if (filename.IsNullOrWhiteSpace())
{
throw new ApplicationException($"未指定{typeof(TConfig).Name}的配置文件路径!");
}
ConcurrentDictionary<string, Ident> idents = ConfigHelper.InitIdents(current);
ConfigHelper.SaveConfigValue(Current, idents);
List<string> strs = new List<string> { "<?xml version=" + "\"" + "1.0" + "\"" + " encoding=" + "\"" + "utf-8" + "\"" + "?> ", "<!--" + Description + "--> " };
strs.Add("<" + GetType().Name + ">");
SortedList<int, Ident> slist = new SortedList<int, Ident>();
foreach (var ident in idents.Values)
{
slist.Add(ident.Index, ident);
}
foreach (var ident in slist.Values)
{
if (!ident.Description.IsNullOrEmpty())
{
strs.Add(" <!--" + ident.Description + "-->");
}
if (!ident.IsList)
{
strs.Add(" <" + ident.Key + ">" + ident.Value + "</" + ident.Key + ">");
}
else
{
strs.Add(" <" + ident.Key + ">");
foreach (string value in ident.Values)
{
strs.Add(" <Value>" + value + "</Value>");
}
strs.Add(" </" + ident.Key + ">");
}
}
strs.Add("</" + GetType().Name + ">");
File.WriteAllLines(filename, strs.ToArray(), Encoding.UTF8);
}
#endregion
}
}

View File

@ -22,7 +22,6 @@
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Sunny.UI.Properties;
namespace Sunny.UI
{
@ -45,7 +44,7 @@ namespace Sunny.UI
Custom,
/// <summary>
/// The GPS
/// The Gps
/// </summary>
Gps,
@ -133,14 +132,14 @@ namespace Sunny.UI
if (value == TMeterType.Gps)
{
BackgroundImage = Resources.gps1;
AngleImage = Resources.gps_postion;
BackgroundImage = Sunny.UI.Properties.Resources.gps1;
AngleImage = Sunny.UI.Properties.Resources.gps_postion;
}
if (value == TMeterType.Wind)
{
BackgroundImage = Resources.wind;
AngleImage = Resources.wind_postion;
BackgroundImage = Sunny.UI.Properties.Resources.wind;
AngleImage = Sunny.UI.Properties.Resources.wind_postion;
}
Invalidate();

View File

@ -97,10 +97,39 @@ namespace Sunny.UI
{
base.OnPaintFill(g, path);
using var bmp = CreateImage(RandomEx.RandomChars(CodeLength));
using var bmp = CreateImage(RandomChars(CodeLength));
g.DrawImage(bmp, Width / 2 - bmp.Width / 2, 1);
}
private const string CHARS_62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
/// <summary>
/// 生成字母和数字的随机字符串
/// </summary>
/// <param name="length">长度</param>
/// <returns>结果</returns>
private static string RandomChars(int length = 10)
{
return RandomBase(CHARS_62.ToCharArray(), length);
}
private static string RandomBase(char[] pattern, int length)
{
if (pattern.IsNullOrEmpty())
{
throw new ArgumentNullException();
}
string result = "";
for (int i = 0; i < length; i++)
{
Random random = new Random(DateTime.Now.Millisecond);
result += pattern[random.Next(0, pattern.Length)];
}
return result;
}
/// <summary>
/// 绘制前景颜色
/// </summary>

View File

@ -20,7 +20,6 @@
* 2023-04-19: V3.3.5
******************************************************************************/
using Sunny.UI.Properties;
using System;
using System.ComponentModel;
@ -96,12 +95,12 @@ namespace Sunny.UI
{
loginImage = value;
if (loginImage == UILoginImage.Login1) BackgroundImage = Resources.Login1;
if (loginImage == UILoginImage.Login2) BackgroundImage = Resources.Login2;
if (loginImage == UILoginImage.Login3) BackgroundImage = Resources.Login3;
if (loginImage == UILoginImage.Login4) BackgroundImage = Resources.Login4;
if (loginImage == UILoginImage.Login5) BackgroundImage = Resources.Login5;
if (loginImage == UILoginImage.Login6) BackgroundImage = Resources.Login6;
if (loginImage == UILoginImage.Login1) BackgroundImage = Sunny.UI.Properties.Resources.Login1;
if (loginImage == UILoginImage.Login2) BackgroundImage = Sunny.UI.Properties.Resources.Login2;
if (loginImage == UILoginImage.Login3) BackgroundImage = Sunny.UI.Properties.Resources.Login3;
if (loginImage == UILoginImage.Login4) BackgroundImage = Sunny.UI.Properties.Resources.Login4;
if (loginImage == UILoginImage.Login5) BackgroundImage = Sunny.UI.Properties.Resources.Login5;
if (loginImage == UILoginImage.Login6) BackgroundImage = Sunny.UI.Properties.Resources.Login6;
}
}
}

View File

@ -19,6 +19,7 @@
* 2020-01-01: V2.2.0
******************************************************************************/
using System.ComponentModel;
using System.Drawing;
namespace Sunny.UI
@ -31,19 +32,19 @@ namespace Sunny.UI
/// <summary>
/// 自定义
/// </summary>
[DisplayText("Custom")]
[Description("Custom")]
Custom,
/// <summary>
/// 黑
/// </summary>
[DisplayText("Black")]
[Description("Black")]
Black,
/// <summary>
/// 白
/// </summary>
[DisplayText("White")]
[Description("White")]
White
}
@ -59,7 +60,7 @@ namespace Sunny.UI
public override string ToString()
{
return Style.DisplayText();
return Style.Description();
}
}

View File

@ -25,6 +25,7 @@
******************************************************************************/
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
@ -55,85 +56,85 @@ namespace Sunny.UI
/// <summary>
/// 继承的全局主题
/// </summary>
[DisplayText("继承的全局主题")]
[Description("继承的全局主题")]
Inherited = -1,
/// <summary>
/// 自定义
/// </summary>
[DisplayText("Custom")]
[Description("Custom")]
Custom = 0,
/// <summary>
/// 蓝
/// </summary>
[DisplayText("Blue")]
[Description("Blue")]
Blue = 1,
/// <summary>
/// 绿
/// </summary>
[DisplayText("Green")]
[Description("Green")]
Green = 2,
/// <summary>
/// 橙
/// </summary>
[DisplayText("Orange")]
[Description("Orange")]
Orange = 3,
/// <summary>
/// 红
/// </summary>
[DisplayText("Red")]
[Description("Red")]
Red = 4,
/// <summary>
/// 灰
/// </summary>
[DisplayText("Gray")]
[Description("Gray")]
Gray = 5,
/// <summary>
/// 紫
/// </summary>
[DisplayText("Purple")]
[Description("Purple")]
Purple = 6,
/// <summary>
/// LayuiGreen
/// </summary>
[DisplayText("LayuiGreen")]
[Description("LayuiGreen")]
LayuiGreen = 7,
/// <summary>
/// LayuiRed
/// </summary>
[DisplayText("LayuiRed")]
[Description("LayuiRed")]
LayuiRed = 8,
/// <summary>
/// LayuiOrange
/// </summary>
[DisplayText("LayuiOrange")]
[Description("LayuiOrange")]
LayuiOrange = 9,
/// <summary>
/// 深蓝
/// </summary>
[DisplayText("DarkBlue")]
[Description("DarkBlue")]
DarkBlue = 101,
/// <summary>
/// 黑
/// </summary>
[DisplayText("Black")]
[Description("Black")]
Black = 102,
/// <summary>
/// 多彩的
/// </summary>
[DisplayText("Colorful")]
[Description("Colorful")]
Colorful = 999
}

View File

@ -419,7 +419,7 @@ namespace Sunny.UI
public override string ToString()
{
return Name.DisplayText();
return Name.Description();
}
public virtual bool BuiltIn => true;

View File

@ -210,10 +210,11 @@ namespace Sunny.UI
string thisFullName = form.GetType().FullName;
string section = "Info";
string inifile = Dir.CurrentDir() + "Language\\" + thisFullName + ".ini";
if (!File.Exists(inifile)) return;
string fullName = Dir.CurrentDir() + "Language\\" + thisFullName + ".ini";
if (!File.Exists(fullName)) return;
IniFile ini = new IniFile(Dir.CurrentDir() + "Language\\" + thisFullName + ".ini", System.Text.Encoding.UTF8);
int count = ini.ReadInt("Controls", "Count", 0);
string readString = ini.ReadString("Controls", "Count", "");
if (!int.TryParse(readString, out int count)) return;
if (count == 0) return;
string key = UIStyles.CultureInfo.LCID.ToString() + ".Name";

View File

@ -72,7 +72,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SunnyUI.Common" Version="3.8.2" />
<PackageReference Include="SunnyUI.Common" Version="3.8.3" />
</ItemGroup>
<ItemGroup>