-
Notifications
You must be signed in to change notification settings - Fork 0
/
SaveFieldsConfigAttribute.cs
365 lines (342 loc) · 15.6 KB
/
SaveFieldsConfigAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.Serialization;
/// <summary>
/// Form值类型控件标记字段是否可以被存储
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class SaveFieldsConfigAttribute : Attribute
{
/// <summary>
/// 属性名称
/// </summary>
public string[] PropertyNames { get; set; }
/// <summary>
///
/// </summary>
/// <param name="PropertyName">属性名称</param>
public SaveFieldsConfigAttribute(params string[] propertyNames)
{
PropertyNames = propertyNames;
}
/// <summary>
/// 保存Form窗体值类型数据至文件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="form">窗体实例</param>
/// <param name="fileName">xml文件路径</param>
/// <returns></returns>
public static void SaveXmlToFile<T>(T form, string fileName) where T : Form
{
BindingFlags filter = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;//过滤器
Type tp = form.GetType();//获取Form类型
var fields = tp.GetFields(filter);//获取共用和私有字段
XDocument xdoc = new XDocument();//创建xml文档
xdoc.Add(new XComment($"窗体界面({form.Text})的参数记录"));
var paramElement = new XElement("UIInputValueList");
xdoc.Add(paramElement);//添加父节点
List<XElement> paramList = new List<XElement>();
fields.ToList().ForEach((field) =>
{
try
{
var att = (SaveFieldsConfigAttribute)field.GetCustomAttributes(true).ToList().
Find(p => p.GetType() == typeof(SaveFieldsConfigAttribute));//寻找SaveFieldsConfigAttribute标记的字段
if (att != null)
{
object RootObj = field.GetValue(form);
if (att.PropertyNames != null && att.PropertyNames.Length != 0)
{
for (int n = 0; n < att.PropertyNames.Length; n++)
{
string propertyName = att.PropertyNames[n];
XElement element = new XElement("item", new XAttribute("Key", field.Name),
new XAttribute("PropertyName", propertyName));
var saveVal = RootObj.GetType().GetProperty(propertyName).GetValue(RootObj);
if (saveVal.GetType().GetInterfaces().Contains(typeof(System.Collections.ICollection)))
{
element.Add(string.Join(",", (saveVal as System.Collections.ICollection).Cast<object>().ToList().Select(p => p.ToString())));
}
else
{
Type saveValType = saveVal.GetType();
element.Add(SerizerObject(saveValType, saveVal));//将对象转化为自定义字符串
}
paramElement.Add(element);//添加子节点
}
}
else
{
XElement element = new XElement("item", new XAttribute("Key", field.Name), new XAttribute("PropertyName", ""));
element.Add(SerizerObject(field.FieldType, field.GetValue(form)));//获取字段值并添加值上一级节点
paramElement.Add(element);//添加子节点
}
}
}
catch (Exception ex)
{
Console.WriteLine("保存配置(Error):" + form.Name + "," + field.Name + "," + ex.Message);
}
});
xdoc.Add(new XComment($"DateTime:{DateTime.Now.ToString()}"));//添加备注
xdoc.Save(fileName);//保存
}
/// <summary>
/// 读取Form窗体值类型数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="form">窗体实例</param>
/// <param name="fileName">xml文件路径</param>
/// <returns></returns>
public static void LoadXmlFromFile<T>(T form, string fileName) where T : Form
{
BindingFlags filter = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;//过滤器
Type tp = form.GetType();
if (!System.IO.File.Exists(fileName)) return;//如果文件不存在
// 加载用户上次输入的配置
XDocument xdoc = XDocument.Load(fileName);
XElement xRoot = xdoc.Element("UIInputValueList");//获取参数父节点
foreach (XElement xele in xRoot.Elements())
{
try
{
string keyName = xele.Attributes().ToList().Find(p => p.Name == "Key").Value;//通过字段名字
var field = tp.GetField(keyName, filter);//通过标记查找字段或属性
if (field == null) continue;
var fieldObj = field.GetValue(form);//通过实例获取字段或属性
Type prop = null;
object val = null;
string propertyName = xele.Attributes().ToList().Find(p => p.Name == "PropertyName").Value;
if (!string.IsNullOrEmpty(propertyName))
{
prop = fieldObj.GetType().GetProperty(propertyName, filter).PropertyType;
}
else
{
prop = field.FieldType;
}
val= DeserializationObject(prop, xele.Value);//将字符串反序列化成对象
if (!string.IsNullOrEmpty(propertyName))
{
if (fieldObj.GetType().GetProperty(propertyName, filter).SetMethod != null & !prop.GetInterfaces().Contains(typeof(System.Collections.ICollection)))
{
fieldObj.GetType().GetProperty(propertyName, filter).SetValue(fieldObj, val);//字段或属性重新赋值
}
else
{
if (prop.GetInterfaces().Contains(typeof(System.Collections.ICollection)))
{
var obj = fieldObj.GetType().GetProperty(propertyName, filter).GetValue(fieldObj);
(fieldObj.GetType().GetProperty(propertyName, filter).GetValue(fieldObj) as
System.Collections.IList).GetType().GetMethod("Clear").Invoke(obj, null);//先清空集合
(val as IList<string>).Cast<object>().ToList().ForEach(item =>//使用集合的Add方法添加
{
(fieldObj.GetType().GetProperty(propertyName, filter).GetValue(fieldObj) as
System.Collections.IList).GetType().GetMethod("Add").Invoke(obj,
new object[] { item });//再重新添加新的至集合
});
}
}
}
else
{
field.SetValue(form, val);//字段或属性重新赋值
}
}
catch (Exception ex)
{
Console.WriteLine("加载配置(Error):" + form.Name + "," + xele.FirstAttribute.Value + "," + ex.Message);
}
}
}
/// <summary>
/// 将实例对象转为自定义字符串
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string SerizerObject(Type type, object saveVal)
{
Type saveValType = type;
string content = "";
if (saveValType == typeof(System.Drawing.Point))// X,Y
{
var tempVal = (System.Drawing.Point)saveVal;
content = string.Format("{0},{1}", tempVal.X, tempVal.Y);//获取字段值并添加值上一级节点
}
if (saveValType == typeof(System.Drawing.PointF))// X,Y
{
var tempVal = (System.Drawing.PointF)saveVal;
content = string.Format("{0},{1}", tempVal.X, tempVal.Y);//获取字段值并添加值上一级节点
}
else if (saveValType == typeof(System.Drawing.SizeF))//Width,Height
{
var tempVal = (System.Drawing.SizeF)saveVal;
content = string.Format("{0},{1}", tempVal.Width, tempVal.Height);//获取字段值并添加值上一级节点
}
else if (saveValType == typeof(System.Drawing.Size))//Width,Height
{
var tempVal = (System.Drawing.Size)saveVal;
content = string.Format("{0},{1}", tempVal.Width, tempVal.Height);//获取字段值并添加值上一级节点
}
else if (saveValType == typeof(System.Drawing.Color))//A,R,G,B
{
var tempVal = (System.Drawing.Color)saveVal;
content = string.Format("{0},{1},{2},{3}", tempVal.A, tempVal.R, tempVal.G, tempVal.B);//获取字段值并添加值上一级节点
}
else if (saveValType == typeof(System.Drawing.Font))//FontName,FontSize
{
var tempVal = (System.Drawing.Font)saveVal;
content = string.Format("{0},{1}", tempVal.Name, tempVal.Size);//获取字段值并添加值上一级节点
}
else if (saveValType == typeof(System.Drawing.Bitmap) || saveValType == typeof(System.Drawing.Image))//Base64String
{
var tempVal = (System.Drawing.Bitmap)saveVal;
content = BitmapToBase64String(tempVal);//获取字段值并添加值上一级节点
}
else if (saveValType == typeof(Padding))//Left,Top,Right,Bottom
{
var tempVal = (Padding)saveVal;
content = string.Format("{0},{1},{2},{3}", tempVal.Left, tempVal.Top,tempVal.Right,tempVal.Bottom);//获取字段值并添加值上一级节点
}
else//可直接转为字符串存储 包括枚举类型
{
content = saveVal.ToString();//获取字段值并添加值上一级节点
}
return content;
}
/// <summary>
/// 将自定义字符串转为实例对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="content"></param>
/// <returns></returns>
public static object DeserializationObject(Type type, string content)
{
Type ValType = type;
object Obj = null;
if (ValType == typeof(int))//解析int 类型
{
Obj = Convert.ToInt32(content);
}
else if (ValType == typeof(double))//解析double 类型
{
Obj = Convert.ToDouble(content);
}
else if (ValType == typeof(decimal))//解析decimal 类型
{
Obj = Convert.ToDecimal(content);
}
else if (ValType == typeof(float))//解析float 类型
{
Obj = Convert.ToSingle(content);
}
else if (ValType == typeof(byte))//解析byte 类型
{
Obj = Convert.ToByte(content);
}
else if (ValType == typeof(bool))//解析bool 类型
{
Obj = Convert.ToBoolean(content);
}
else if (ValType == typeof(System.Drawing.Point))//解析point 类型
{
string[] values = content.Split(',');
Obj = new System.Drawing.Point(Convert.ToInt32(values[0]), Convert.ToInt32(values[1]));
}
else if (ValType == typeof(System.Drawing.PointF))//解析PointF 类型
{
string[] values = content.Split(',');
Obj = new System.Drawing.PointF(Convert.ToSingle(values[0]), Convert.ToSingle(values[1]));
}
else if (ValType == typeof(System.Drawing.Color))//解析Color 类型
{
string[] values = content.Split(',');
Obj = System.Drawing.Color.FromArgb(Convert.ToInt32(values[0]), Convert.ToInt32(values[1]),
Convert.ToInt32(values[2]), Convert.ToInt32(values[3]));
}
else if (ValType == typeof(System.Drawing.Size))//解析Size 类型
{
string[] values = content.Split(',');
Obj = new System.Drawing.Size(Convert.ToInt32(values[0]), Convert.ToInt32(values[1]));
}
else if (ValType == typeof(System.Drawing.SizeF))//解析SizeF 类型
{
string[] values = content.Split(',');
Obj = new System.Drawing.SizeF(Convert.ToSingle(values[0]), Convert.ToSingle(values[1]));
}
else if (ValType == typeof(System.Drawing.Font))//解析Font 类型
{
string[] values = content.Split(',');
Obj = new System.Drawing.Font(values[0], Convert.ToSingle(values[1]));
}
else if (ValType.IsEnum)//解析枚举 类型
{
Array EnumArray = ValType.GetEnumValues();
foreach (var item in EnumArray)
{
if (item.ToString() == content)
{
Obj = item;
break;
}
}
}
else if (ValType == typeof(System.Drawing.Image) || ValType == typeof(System.Drawing.Bitmap))//解析图片 类型
{
Obj = Base64StringToBitmap(content);
}
else if (ValType == typeof(Padding))//Left,Top,Right,Bottom
{
string[] values = content.Split(',');
Obj = new Padding(Convert.ToInt32(values[0]), Convert.ToInt32(values[1]),
Convert.ToInt32(values[2]), Convert.ToInt32(values[3]));//获取字段值并添加值上一级节点
}
else if (ValType.GetInterfaces().Contains(typeof(System.Collections.ICollection)))//解析集合 类型
{
Obj = (System.Collections.ICollection)(content.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList());
}
else//解析字符串类型及其他
{
Obj = content;
}
return Obj;
}
/// <summary>
/// 将Bitmap类型转为base64字符串
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static string BitmapToBase64String(System.Drawing.Bitmap bmp)
{
//字面是对当前图片进行了二进制转换
MemoryStream ms = new MemoryStream();
bmp.Save(ms, bmp.RawFormat);
byte[] arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(arr, 0, (int)ms.Length);
ms.Close();
//这里将arr强转Base64
return Convert.ToBase64String(arr);
}
/// <summary>
/// base64字符串转为将Bitmap类型
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static System.Drawing.Bitmap Base64StringToBitmap(string base64String)
{
//将base64强转图片
base64String = base64String.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", "");//将base64头部信息替换
byte[] bytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(bytes);
System.Drawing.Image mImage = System.Drawing.Image.FromStream(ms);
return new System.Drawing.Bitmap(ms);
}
}