EntityBase.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using Newtonsoft.Json;
  2. using Newtonsoft.Json.Linq;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.ComponentModel.DataAnnotations;
  7. using System.Data.Linq.Mapping;
  8. using System.Drawing;
  9. using System.Linq;
  10. using System.Reflection;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. namespace PTMedicalInsurance.Entity
  15. {
  16. /// <summary>
  17. /// 后面出入参基本集成该类,将一些通用方法封装于该类
  18. /// 基线版的出入参需要包含Column属性,数据库字段名成,数据库字段类型(可以为入参给定类型)等
  19. /// 需要包含StringLength 属性,标明在表格中显示的宽度,实际显示宽度值 = 长度 * 字体大概像素宽度,其中各种字体的不同SIZE对应的像素宽度是不同的,具体每个字符的像素宽度也是不同的,因此只能估计
  20. /// 包含DisplayName属性,在表中的标题显示
  21. /// 以上属性均进行为空判断
  22. /// </summary>
  23. public class EntityBase
  24. {
  25. /// <summary>
  26. /// 动态增加datagridview列
  27. /// </summary>
  28. /// <param name="dgv"></param>
  29. /// <param name="headerText"></param>
  30. /// <param name="dataPropertyName"></param>
  31. protected void AddDGVColumn(DataGridView dgv, string headerText, string dataPropertyName, int width = 120,bool isAdapter = false)
  32. {
  33. DataGridViewColumn newColumn = new DataGridViewTextBoxColumn();
  34. newColumn.HeaderText = headerText;
  35. newColumn.Width = width;
  36. newColumn.DataPropertyName = dataPropertyName;
  37. newColumn.Name = dataPropertyName;
  38. if (isAdapter) newColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
  39. dgv.Columns.Add(newColumn);
  40. }
  41. public void SetHeaderText(DataGridView dgv,Font font)
  42. {
  43. Type type = this.GetType();
  44. var properties = type.GetProperties();
  45. dgv.AutoGenerateColumns = false;
  46. dgv.Columns.Clear();
  47. dgv.Font = font;
  48. foreach (var property in properties)
  49. {
  50. //获取显示名称
  51. var display = property.GetCustomAttribute<DisplayNameAttribute>();
  52. if (display == null) continue;
  53. string dispalyName = display.DisplayName;
  54. int disLen = CalculateVarCharLength(dispalyName);
  55. var strLength = property.GetCustomAttribute<StringLengthAttribute>();
  56. if (strLength == null) continue;
  57. int len = strLength.MaximumLength;
  58. int width = len>disLen ? (int)(len*6.5f) : (int)(disLen * 6.5f);
  59. bool isAdapter = width > 200;
  60. AddDGVColumn(dgv, dispalyName, property.Name, width,isAdapter);
  61. }
  62. dgv.CellValueChanged += DataGridView_CellValueChanged;
  63. }
  64. //public void FillDgv(DataGridView dgv, Font font,string data)
  65. //{
  66. // SetHeaderText(dgv,font);
  67. // List<this.GetType> lst = JsonConvert.DeserializeObject<List<this.GetType>> (data);
  68. // dgv.DataSource = lst;
  69. //}
  70. /// <summary>
  71. /// 计算字符串在 VarChar 类型中的长度(以字节为单位)
  72. /// </summary>
  73. /// <param name="input">要计算长度的字符串</param>
  74. /// <returns>字符串在 VarChar 类型中的长度</returns>
  75. public static int CalculateVarCharLength(string input)
  76. {
  77. // 使用 UTF-16 编码计算字符串的字节数
  78. Encoding utf16Encoding = Encoding.UTF8;
  79. byte[] bytes = utf16Encoding.GetBytes(input);
  80. return bytes.Length;
  81. }
  82. /// <summary>
  83. /// 将实体类转换为数据库入参(Json)
  84. /// </summary>
  85. public JObject ConvertToDBJson()
  86. {
  87. Type type = this.GetType();
  88. var properties = type.GetProperties();
  89. JObject joRtn = new JObject();
  90. foreach (var property in properties)
  91. {
  92. var attribute = property.GetCustomAttribute<ColumnAttribute>();
  93. if (attribute == null) continue;
  94. string fieldName = attribute.Name;
  95. // 使用 BindingFlags 来允许访问非公共属性
  96. object value = property.GetValue(this, null);
  97. // 保持原始数据类型
  98. JToken token = value == null ? JValue.CreateNull() : JToken.FromObject(value);
  99. joRtn.Add(fieldName, token);
  100. }
  101. return joRtn;
  102. }
  103. public JObject ToJson()
  104. {
  105. string jsonString = JsonConvert.SerializeObject(this);
  106. return JObject.Parse(jsonString);
  107. }
  108. private static void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
  109. {
  110. // 只有在最后一列编辑完成时才会触发此事件
  111. if (e.RowIndex == -1 && e.ColumnIndex == -1)
  112. {
  113. AdjustColumnWidths((DataGridView)sender);
  114. }
  115. }
  116. private static void AdjustColumnWidths(DataGridView dataGridView)
  117. {
  118. for (int i = 0; i < dataGridView.Columns.Count; i++)
  119. {
  120. DataGridViewColumn column = dataGridView.Columns[i];
  121. // 获取列标题的宽度
  122. float titleSize = CalculateVarCharLength(column.HeaderText);
  123. float maxWidth = titleSize;
  124. // 遍历每一行
  125. foreach (DataGridViewRow row in dataGridView.Rows)
  126. {
  127. if (!row.IsNewRow && !string.IsNullOrEmpty(row.Cells[i].Value?.ToString()))
  128. {
  129. float cellSize = CalculateVarCharLength(row.Cells[i].Value.ToString());
  130. maxWidth = Math.Max(maxWidth, cellSize);
  131. }
  132. }
  133. // 设置列宽
  134. column.Width = (int)Math.Ceiling(maxWidth) + 5; // 加上一点额外空间
  135. }
  136. }
  137. }
  138. public static class EntityBasemExtensions
  139. {
  140. /// <summary>
  141. /// 扩展方法,用于自动设置 DataGridView 的列头
  142. /// </summary>
  143. public static void FillDgv<T>(this EntityBase entity, DataGridView dgv, Font font,string data) where T : class
  144. {
  145. entity.SetHeaderText(dgv,font);
  146. List < T> lst = JsonConvert.DeserializeObject < List < T>> (data);
  147. dgv.DataSource = lst;
  148. }
  149. }
  150. }