UCDispVpp.xaml.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Data;
  9. using System.Windows.Documents;
  10. using System.Windows.Input;
  11. using System.Windows.Media;
  12. using System.Windows.Media.Imaging;
  13. using System.Windows.Navigation;
  14. using System.Windows.Shapes;
  15. namespace Plugins.Vpp.Views
  16. {
  17. /// <summary>
  18. /// UCDispVpp.xaml 的交互逻辑
  19. /// </summary>
  20. public partial class UCDispVpp : UserControl
  21. {
  22. public UCDispVpp()
  23. {
  24. InitializeComponent();
  25. }
  26. #region 属性
  27. int[] _RowColNumber = new int[2];
  28. internal object obj = new object();
  29. public int[] RowColNumber
  30. {
  31. get { return _RowColNumber; }
  32. set
  33. {
  34. lock (obj)
  35. {
  36. AddHalconCv(value[0], value[1]);
  37. _RowColNumber = value;
  38. }
  39. }
  40. }
  41. private int DoubleVppNumber = -1;
  42. private VppWindow DoubleWindow = null;
  43. public List<VppWindow> vppWindow = new List<VppWindow>();
  44. private static UCDispVpp _instance = new UCDispVpp();
  45. public static UCDispVpp Instance
  46. {
  47. get { return _instance; }
  48. }
  49. #endregion
  50. #region 方法
  51. /// <summary>
  52. /// 添加Vpp窗体控件:
  53. /// - 按 GetColRow 最优行列布局,但只创建 num 个窗体(不补空白格);
  54. /// - 数量除不尽时,最后一个窗体直接跨列填满本行剩余位置。
  55. /// </summary>
  56. /// <param name="num">画面数量</param>
  57. /// <param name="array">排列方式:1=水平方向优先,2=垂直方向优先</param>
  58. public void AddHalconCv(int num, int array)
  59. {
  60. try
  61. {
  62. UCDispVpp.Instance.vppWindow.Clear();
  63. Task.Delay(100).Wait();
  64. UCDispVpp.Instance.GetColRow(num, out int row, out int col);
  65. if (array == 2) (row, col) = (col, row); // 垂直方向优先:交换行列倾向
  66. foreach (var item in UCDispVpp.Instance.vppWindow)
  67. {
  68. Application.Current.Dispatcher.Invoke(() =>
  69. {
  70. item.MouseDouble -= UCDispVpp_MouseDoubleClick;
  71. });
  72. }
  73. if (DoubleVppNumber >=0&& DoubleWindow!=null)
  74. Application.Current.Dispatcher.Invoke(() => UCDispVppChildren_MouseDoubleClick(DoubleWindow, DoubleVppNumber));
  75. Application.Current.Dispatcher.Invoke(() => UCDispVpp.Instance.VppGrid.Children.Clear());
  76. Application.Current.Dispatcher.Invoke(new Action(() =>
  77. {
  78. // 重建等分行列定义
  79. var grid = UCDispVpp.Instance.VppGrid;
  80. grid.RowDefinitions.Clear();
  81. grid.ColumnDefinitions.Clear();
  82. for (int r = 0; r < row; r++)
  83. grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  84. for (int c = 0; c < col; c++)
  85. grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  86. }));
  87. Task.Delay(100).Wait();
  88. for (int i = 0; i < num; i++)
  89. {
  90. Application.Current.Dispatcher.Invoke(() =>
  91. {
  92. UCDispVpp.Instance.vppWindow.Add(new VppWindow(i + 1));
  93. });
  94. Task.Delay(100).Wait();
  95. }
  96. for (int i = 0; i < num; i++)
  97. {
  98. Application.Current.Dispatcher.Invoke(() =>
  99. {
  100. var w = UCDispVpp.Instance.vppWindow[i];
  101. int r, c;
  102. if (array == 2)
  103. {
  104. // 垂直优先:按列顺序填充(先填满一列再换下一列)
  105. c = i / row;
  106. r = i % row;
  107. // 数量除不尽时:最后一个窗体跨行填满本列剩余位置(垂直合页)
  108. if (i == num - 1 && row - r > 1)
  109. Grid.SetRowSpan(w, row - r);
  110. }
  111. else
  112. {
  113. // 水平优先:按行顺序填充(先填满一行再换下一行)
  114. r = i / col;
  115. c = i % col;
  116. // 数量除不尽时:最后一个窗体跨列填满本行剩余位置(水平合页,不补空白格)
  117. if (i == num - 1 && col - c > 1)
  118. Grid.SetColumnSpan(w, col - c);
  119. }
  120. Grid.SetRow(w, r);
  121. Grid.SetColumn(w, c);
  122. UCDispVpp.Instance.VppGrid.Children.Add(w);
  123. w.MouseDouble += UCDispVpp_MouseDoubleClick;
  124. });
  125. Task.Delay(100).Wait();
  126. }
  127. }
  128. catch (Exception ex)
  129. {
  130. throw ex;
  131. }
  132. }
  133. private void UCDispVpp_MouseDoubleClick(VppWindow window, int VppNumber)
  134. {
  135. DoubleVppNumber = VppNumber;
  136. DoubleWindow=window;
  137. window.MouseDouble -= UCDispVpp_MouseDoubleClick;
  138. VppGrid.Visibility = Visibility.Collapsed;
  139. UCDispVpp.Instance.VppGrid.Children.Remove(window);
  140. MaxVppGrid.Children.Clear();
  141. MaxVppGrid.Children.Add(window);
  142. MaxVppGrid.Visibility = Visibility.Visible;
  143. window.SetStatusBarVisible(true); // enlarge: show coordinate status bar
  144. window.MouseDouble += UCDispVppChildren_MouseDoubleClick;
  145. }
  146. private void UCDispVppChildren_MouseDoubleClick(VppWindow window, int VppNumber)
  147. {
  148. MaxVppGrid.Children.Clear();
  149. MaxVppGrid.Visibility = Visibility.Collapsed;
  150. //UCDispVpp.Instance.VppGrid.Children.Add(window);
  151. UCDispVpp.Instance.VppGrid.Children.Insert(VppNumber - 1, window);
  152. window.MouseDouble -= UCDispVppChildren_MouseDoubleClick;
  153. window.MouseDouble += UCDispVpp_MouseDoubleClick;
  154. VppGrid.Visibility = Visibility.Visible;
  155. window.SetStatusBarVisible(false); // restore grid preview: hide coordinate status bar
  156. DoubleVppNumber = -1;
  157. DoubleWindow = null;
  158. }
  159. #endregion
  160. #region 计算行列
  161. /// <summary>
  162. /// 查询能被整除的最大数
  163. /// </summary>
  164. /// <param name="target"></param>
  165. /// <returns></returns>
  166. public static int FindLargestDivisor(int target)
  167. {
  168. int max = target; // 初始最大数为目标数本身
  169. List<int> list = new List<int>();
  170. for (int i = 1; i < target; i++)
  171. {
  172. if (target % i == 0)
  173. {
  174. list.Add(i);
  175. //max = i;
  176. }
  177. }
  178. max = list[list.Count / 2];
  179. return max;
  180. }
  181. /// <summary>
  182. /// 计算出最优行数和列数
  183. /// </summary>
  184. /// <param name="target">总计数量</param>
  185. /// <param name="col">列数</param>
  186. /// <param name="row">行数</param>
  187. public void GetColRow(int target, out int row, out int col)
  188. {
  189. if (target <= 2)
  190. {
  191. row = target > 0 ? target : 1;
  192. col = 1;
  193. return;
  194. }
  195. col = FindLargestDivisor(target);
  196. Console.WriteLine("1:" + col);
  197. if (col == 1)
  198. {
  199. col = FindLargestDivisor(target + 1);
  200. row = (target + 1) / col;
  201. }
  202. else
  203. row = target / col;
  204. }
  205. #endregion
  206. }
  207. }