PatternBrick.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. using CustomControls.Pattern.DataModels;
  7. using DevExpress.Utils;
  8. using DevExpress.Utils.Serializing;
  9. using DevExpress.XtraPrinting;
  10. using DevExpress.XtraPrinting.BrickExporters;
  11. using DevExpress.XtraPrinting.Native;
  12. using DevExpress.XtraReports.UI;
  13. namespace CustomControls.Pattern
  14. {
  15. [BrickExporter(typeof(PatternBrickExporter))]
  16. public class PatternBrick : PanelBrick
  17. {
  18. #region 变量和属性
  19. /// <summary>
  20. /// 数据源
  21. /// </summary>
  22. internal PatternDataItem PatternDataItem { get; set; }
  23. /// <summary>
  24. /// 文本设置
  25. /// </summary>
  26. [XtraSerializableProperty(XtraSerializationVisibility.Content)]
  27. public CodeOptions CodeOptions { get; } = new CodeOptions();
  28. /// <summary>
  29. /// 字体
  30. /// </summary>
  31. private string FontFamily => CodeOptions.FontFamily.ToString();
  32. /// <summary>
  33. /// 字号
  34. /// </summary>
  35. private int FontSize => CodeOptions.FontSize;
  36. /// <summary>
  37. /// 字体类型
  38. /// </summary>
  39. private FontStyle FontStyle => CodeOptions.FontStyle;
  40. /// <summary>
  41. /// 左边
  42. /// </summary>
  43. internal List<PointF> LeftCodePointFs = new List<PointF>();
  44. /// <summary>
  45. /// 布身
  46. /// </summary>
  47. internal List<PointF> MiddleCodePointFs = new List<PointF>();
  48. /// <summary>
  49. /// 余花
  50. /// </summary>
  51. internal List<PointF> SurplusCodePointFs = new List<PointF>();
  52. /// <summary>
  53. /// 右边
  54. /// </summary>
  55. internal List<PointF> RightCodePointFs = new List<PointF>();
  56. /// <summary>
  57. /// 循环位置
  58. /// </summary>
  59. internal PointF CountFs;
  60. /// <summary>
  61. /// 文本框尺寸
  62. /// </summary>
  63. internal float FontHeight;
  64. private int index;
  65. #endregion
  66. #region 构造函数
  67. public PatternBrick() : this(null)
  68. {
  69. }
  70. public PatternBrick(IBrickOwner brickOwner) : base(brickOwner)
  71. {
  72. BackColor = Color.Transparent;
  73. Sides = BorderSide.None;
  74. }
  75. #endregion
  76. public override string BrickType => nameof(PatternBrick);
  77. #region 对外方法
  78. /// <summary>
  79. /// 生成内容
  80. /// </summary>
  81. public void GenerateContent(PatternDataItem patternDataItem)
  82. {
  83. /* 记录花型数据 */
  84. PatternDataItem = patternDataItem;
  85. /* 根据数据创建花型 */
  86. CreatePatternPart(patternDataItem.PatternData);
  87. }
  88. #endregion
  89. #region 内部方法
  90. /// <summary>
  91. /// 根据数据创建花型
  92. /// </summary>
  93. private void CreatePatternPart(string patternData)
  94. {
  95. if (string.IsNullOrWhiteSpace(patternData)) { return; }
  96. /* 获取字体高度 */
  97. var font = CreateFont(FontFamily, FontSize, FontStyle);
  98. FontHeight = GetFontHeight(font);
  99. /* 拆分字符串,获取左、中、右、余花排列 */
  100. var threads = patternData.Split('|');
  101. /* 循环添加 */
  102. index = 0;
  103. for (int i = 0; i < threads.Length; i++)
  104. {
  105. List<PointF> pointFs = new List<PointF>();
  106. switch (i)
  107. {
  108. case 0:
  109. pointFs = LeftCodePointFs;
  110. break;
  111. case 1:
  112. pointFs = MiddleCodePointFs;
  113. break;
  114. case 2:
  115. pointFs = SurplusCodePointFs;
  116. break;
  117. case 3:
  118. pointFs = RightCodePointFs;
  119. break;
  120. }
  121. AddThreadBrick(pointFs, threads[i], font);
  122. }
  123. /* 获取循环位置 */
  124. var allPointFs = LeftCodePointFs.Concat(MiddleCodePointFs).Concat(SurplusCodePointFs).Concat(RightCodePointFs).ToList();
  125. var lowestPointF = allPointFs.OrderByDescending(x => x.Y).First();
  126. var countX = MiddleCodePointFs[0].X + (MiddleCodePointFs[MiddleCodePointFs.Count - 1].X - MiddleCodePointFs[0].X) / 2;
  127. CountFs = new PointF(countX, lowestPointF.Y + PatternDataItem.RowSpace + FontHeight);
  128. /* 添加循环控件 */
  129. var rectangleF = new RectangleF(countX, lowestPointF.Y + PatternDataItem.RowSpace, FontHeight * 2, FontHeight);
  130. var countText = CreateTextBirck(threads[threads.Length - 1], font, rectangleF);
  131. Bricks.Add(countText);
  132. }
  133. /// <summary>
  134. /// 添加花型控件
  135. /// </summary>
  136. private void AddThreadBrick(List<PointF> pointFs, string thread, Font font)
  137. {
  138. /* 获取所有字母 */
  139. var strLatter = Regex.Replace(thread, "[0-9]", "", RegexOptions.IgnoreCase);
  140. /* 循环添加 */
  141. for (var i = 0; i < strLatter.Length; i++)
  142. {
  143. Enum.TryParse(strLatter[i].ToString(), out ColorCode code);
  144. /* 确定控件位置 */
  145. var rectangleF = GetRectangleF(index, (int)code, FontHeight);
  146. /* 获取文本 */
  147. var index1 = i == 0 ? 0 : thread.IndexOf(strLatter[i - 1]);
  148. var index2 = thread.IndexOf(strLatter[i]);
  149. var text = thread.Substring(index1 + 1, index2 - index1 - 1);
  150. /* 创建控件 */
  151. var textBrick = CreateTextBirck(text, font, rectangleF);
  152. /* 记录控件坐标 */
  153. pointFs.Add(rectangleF.Location);
  154. /* 添加控件 */
  155. Bricks.Add(textBrick);
  156. thread = thread.Remove(0, index2);
  157. index++;
  158. }
  159. }
  160. /// <summary>
  161. /// 获取文本大小和位置
  162. /// </summary>
  163. private RectangleF GetRectangleF(int index, int codeIndex, float heigh)
  164. {
  165. var x = PatternDataItem.ColumnSpace * index + 5f;
  166. var y = PatternDataItem.RowSpace * codeIndex + 1f;
  167. return new RectangleF(x, y, heigh * 2, heigh);
  168. }
  169. /// <summary>
  170. /// 创建文本
  171. /// </summary>
  172. private static TextBrick CreateTextBirck(string text, Font font, RectangleF bounds)
  173. {
  174. return new TextBrick(CreateBrickStyle(font))
  175. {
  176. Rect = bounds,
  177. Text = text,
  178. HorzAlignment = HorzAlignment.Center,
  179. VertAlignment = VertAlignment.Center,
  180. };
  181. }
  182. /// <summary>
  183. /// 设置样式
  184. /// </summary>
  185. private static BrickStyle CreateBrickStyle(Font font)
  186. {
  187. return new XRControlStyle()
  188. {
  189. Font = font,
  190. Padding = new PaddingInfo(1, 1, 0, 0, 96),
  191. StringFormat = BrickStringFormat.Create(TextAlignment.TopLeft, true, StringTrimming.EllipsisCharacter,
  192. false)
  193. };
  194. }
  195. /// <summary>
  196. /// 获取字体高度
  197. /// </summary>
  198. private static float GetFontHeight(Font font)
  199. {
  200. var metrics = new FontMetrics(font, GraphicsUnit.Document);
  201. var height = metrics.CalculateHeight(1);
  202. return height;
  203. }
  204. /// <summary>
  205. /// 设置字体
  206. /// </summary>
  207. private static Font CreateFont(string fontFamily, int fontSize, FontStyle fontStyle) =>
  208. new Font(fontFamily, fontSize, fontStyle);
  209. #endregion
  210. }
  211. }