RecipeEditorControl.xaml.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Text.RegularExpressions;
  7. using System.Threading;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Documents;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. using System.Windows.Navigation;
  16. using System.Windows.Shapes;
  17. using System.Collections.ObjectModel;
  18. using Xceed.Wpf.DataGrid;
  19. using System.Xml;
  20. using System.IO;
  21. using System.Runtime.Serialization.Formatters.Binary;
  22. using System.Diagnostics;
  23. using System.Windows.Controls.Primitives;
  24. namespace Aitex.UI.RecipeEditor
  25. {
  26. /// <summary>
  27. /// Interaction logic for RecipeEditorControl.xaml
  28. /// </summary>
  29. public partial class RecipeEditorControl : UserControl
  30. {
  31. public RecipeEditorControl()
  32. {
  33. InitializeComponent();
  34. ControlViewModel = new RecipeEditorControlViewModel() { DataGridStackPanel = stackPanel1};
  35. Loaded += new RoutedEventHandler(RecipeEditorView_Loaded);
  36. //dataGrid1.ItemsSource = students;
  37. }
  38. /// <summary>
  39. /// indicate whether recipe modified
  40. /// </summary>
  41. public bool IsRecipeModified
  42. {
  43. get { return ControlViewModel.IsRecipeModified; }
  44. }
  45. /// <summary>
  46. /// RecipeEditor's view model
  47. /// </summary>
  48. public RecipeEditorControlViewModel ControlViewModel { get; set; }
  49. /// <summary>
  50. /// mask recipe item display
  51. /// </summary>
  52. /// <param name="maskedTechNames"></param>
  53. //public void SetDisplayMask(HashSet<string> maskedTechNames = null, HashSet<string> maskedCatalogNames = null)
  54. //{
  55. // if (ControlViewModel != null)
  56. // {
  57. // ControlViewModel.MaskedTechNames = maskedTechNames;
  58. // ControlViewModel.MaskedCatalogNames = maskedCatalogNames;
  59. // ControlViewModel.RefreshCellsDisplay(false);
  60. // }
  61. //}
  62. //public void SetEnableBarcode(bool enabled)
  63. //{
  64. // if (ControlViewModel != null)
  65. // {
  66. // ControlViewModel.EnableBarcode(enabled);
  67. // }
  68. //}
  69. //public void SetEndPointDefaultValue(string defaultValue)
  70. //{
  71. // if (ControlViewModel != null)
  72. // {
  73. // ControlViewModel.SetEndPointDefaultValue(defaultValue);
  74. // }
  75. //}
  76. /// <summary>
  77. /// loaded handling
  78. /// </summary>
  79. /// <param name="sender"></param>
  80. /// <param name="e"></param>
  81. void RecipeEditorView_Loaded(object sender, RoutedEventArgs e)
  82. {
  83. grid1.DataContext = ControlViewModel;
  84. }
  85. /// <summary>
  86. /// open recipe file
  87. /// </summary>
  88. /// <param name="sender"></param>
  89. /// <param name="e"></param>
  90. private void OpenButtonPanelLoaded(object sender, RoutedEventArgs e)
  91. {
  92. try
  93. {
  94. string variation = (string)((Button)sender).Tag;
  95. ControlViewModel.OpenLocalRecipe(variation);
  96. }
  97. catch (Exception ex)
  98. {
  99. System.Diagnostics.Debug.WriteLine(ex.Message);
  100. }
  101. }
  102. /// <summary>
  103. /// update recipe variations
  104. /// </summary>
  105. /// <param name="sender"></param>
  106. /// <param name="e"></param>
  107. private void NewButtonPanelLoaded(object sender, RoutedEventArgs e)
  108. {
  109. try
  110. {
  111. string variation = (string)((Button)sender).Tag;
  112. //newButton.IsOpen = false;
  113. XmlDocument doc = new XmlDocument();
  114. var dir = new System.IO.FileInfo(Process.GetCurrentProcess().MainModule.FileName).Directory;
  115. string xmlPath = dir + "\\Config\\" + variation + ".xml";
  116. doc.Load(xmlPath);
  117. //ControlViewModel.LoadRecipe(doc.SelectSingleNode("/Aitex/TableRecipeFormat").OuterXml, doc.SelectSingleNode("/Aitex/TableRecipeData").OuterXml);
  118. }
  119. catch (Exception ex)
  120. {
  121. System.Diagnostics.Debug.WriteLine(ex.Message);
  122. }
  123. }
  124. private void UIElement_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
  125. {
  126. e.Handled = !IsTextAllowed(e.Text);
  127. }
  128. private static bool IsTextAllowed(string text)
  129. {
  130. return true;
  131. //Regex regex = new Regex("[^0-9.-]+"); //regex that matches disallowed text
  132. //return !regex.IsMatch(text);
  133. }
  134. }
  135. public class GridOptions
  136. {
  137. //暂时不处理实时显示的事情
  138. #region 显示边框信息
  139. public static readonly DependencyProperty ShowBorderProperty =
  140. DependencyProperty.RegisterAttached("ShowBorder", typeof(bool), typeof(GridOptions)
  141. , new PropertyMetadata(OnShowBorderChanged));
  142. public static bool GetShowBorder(DependencyObject obj)
  143. {
  144. return (bool)obj.GetValue(ShowBorderProperty);
  145. }
  146. private static bool flag = false;
  147. public static void SetShowBorder(DependencyObject obj, bool value)
  148. {
  149. obj.SetValue(ShowBorderProperty, value);
  150. }
  151. public static void OnShowBorderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  152. {
  153. var grid = d as Grid;
  154. if ((bool)e.OldValue)
  155. grid.Loaded -= (s, arg) => { };
  156. else
  157. {
  158. grid.Loaded += new RoutedEventHandler(GridLoaded);
  159. }
  160. }
  161. #endregion
  162. #region 线宽信息
  163. public static readonly DependencyProperty LineThicknessProperty =
  164. DependencyProperty.RegisterAttached("LineThickness", typeof(double), typeof(GridOptions),
  165. new PropertyMetadata(1d, OnGridLineThicknessChanged));
  166. public static double GetLineThickness(DependencyObject obj)
  167. {
  168. return (double)obj.GetValue(LineThicknessProperty);
  169. }
  170. public static void SetLineThickness(DependencyObject obj, double value)
  171. {
  172. obj.SetValue(LineThicknessProperty, value);
  173. }
  174. public static void OnGridLineThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  175. {
  176. }
  177. #endregion
  178. public static readonly DependencyProperty LineBrushProperty =
  179. DependencyProperty.RegisterAttached("LineBrush", typeof(Brush), typeof(GridOptions),
  180. new PropertyMetadata(Brushes.Gray, OnGridLineBrushChanged));
  181. #region 线画刷问题
  182. public static Brush GetLineBrush(DependencyObject obj)
  183. {
  184. var brush = (Brush)obj.GetValue(LineBrushProperty);
  185. return brush ?? Brushes.LightGray;
  186. }
  187. public static void SetLineBrush(DependencyObject obj, Brush value)
  188. {
  189. obj.SetValue(LineBrushProperty, value);
  190. }
  191. public static void OnGridLineBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  192. {
  193. }
  194. #endregion
  195. private static void GridLoaded(object sender, RoutedEventArgs e)
  196. {
  197. #region 思路
  198. /*
  199. * 1、覆盖所有单元格都要包围上边框。
  200. * 2、边框线不能存在重复。每个单元格绘制【右下】部分,主体绘制右上部分
  201. */
  202. #endregion
  203. var grid = sender as Grid;
  204. foreach (UIElement item in grid.Children)
  205. {
  206. if (item is Border)
  207. {
  208. return;
  209. }
  210. }
  211. var rowCount = Math.Max(1, grid.RowDefinitions.Count);
  212. var columnCount = Math.Max(1, grid.ColumnDefinitions.Count);
  213. #region 初始化标准数组
  214. int[,] flagArray = new int[rowCount, columnCount];
  215. #endregion
  216. var controls = grid.Children;
  217. var count = controls.Count;
  218. var settingThickness = GetLineThickness(grid);
  219. var borderBrush = GetLineBrush(grid);
  220. for (int i = 0; i < count; i++)
  221. {
  222. var item = controls[i] as FrameworkElement;
  223. var row = Grid.GetRow((item));
  224. var column = Grid.GetColumn(item);
  225. var rowSpan = Grid.GetRowSpan(item);
  226. var columnSpan = Grid.GetColumnSpan(item);
  227. for (int rowTemp = 0; rowTemp < rowSpan; rowTemp++)
  228. {
  229. for (int colTemp = 0; colTemp < columnSpan; colTemp++)
  230. {
  231. flagArray[rowTemp + row, colTemp + column] = 1;
  232. }
  233. }
  234. var border = CreateBorder(row, column, rowSpan, columnSpan, settingThickness);
  235. border.BorderBrush = borderBrush;
  236. grid.Children.RemoveAt(i);
  237. border.Child = item;
  238. grid.Children.Insert(i, border);
  239. }
  240. #region 整理为填充单元格
  241. for (int i = 0; i < rowCount; i++)
  242. {
  243. for (int k = 0; k < columnCount; k++)
  244. {
  245. if (flagArray[i, k] == 0)
  246. {
  247. var border = CreateBorder(i, k, 1, 1, settingThickness);
  248. border.BorderBrush = borderBrush;
  249. grid.Children.Add(border);
  250. }
  251. }
  252. }
  253. #endregion
  254. }
  255. private static Border CreateBorder(int row, int column, int rowSpan, int columnSpan, double thickness)
  256. {
  257. var useThickness = new Thickness(0, 0, thickness, thickness);
  258. if (row == 0)
  259. useThickness.Top = thickness;
  260. if (column == 0)
  261. useThickness.Left = thickness;
  262. var border = new Border()
  263. {
  264. BorderThickness = useThickness,
  265. };
  266. Grid.SetRow(border, row);
  267. Grid.SetColumn(border, column);
  268. Grid.SetRowSpan(border, rowSpan);
  269. Grid.SetColumnSpan(border, columnSpan);
  270. return border;
  271. }
  272. }
  273. public class ItemsControlHelper
  274. {
  275. /// <summary>
  276. /// 绑定 enum 类型所有值给 ItemsSource 赋值
  277. /// 必须绑定 SelectedItem
  278. /// </summary>
  279. public static readonly DependencyProperty EnumValuesToItemsSourceProperty = DependencyProperty.RegisterAttached(
  280. "EnumValuesToItemsSource", typeof(bool), typeof(ItemsControlHelper), new PropertyMetadata(default(bool), OnEnumValuesToItemsSourceChanged));
  281. public static void SetEnumValuesToItemsSource(DependencyObject element, bool value)
  282. {
  283. element.SetValue(EnumValuesToItemsSourceProperty, value);
  284. }
  285. public static bool GetEnumValuesToItemsSource(DependencyObject element)
  286. {
  287. return (bool)element.GetValue(EnumValuesToItemsSourceProperty);
  288. }
  289. private static void OnEnumValuesToItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  290. {
  291. if (d is ItemsControl itemsControl && GetEnumValuesToItemsSource(itemsControl))
  292. {
  293. if (itemsControl.IsLoaded)
  294. {
  295. SetItemsSource(itemsControl);
  296. }
  297. else
  298. {
  299. itemsControl.Loaded += ItemsControl_Loaded;
  300. }
  301. }
  302. }
  303. private static void SetItemsSource(ItemsControl itemsControl)
  304. {
  305. var itemsBindingExpression = BindingOperations.GetBinding(itemsControl, ItemsControl.ItemsSourceProperty);
  306. if (itemsBindingExpression != null)
  307. {
  308. throw new InvalidOperationException("When using ItemsControlHelper.EnumValuesToItemsSource, cannot be used ItemsSource at the same time.");
  309. }
  310. if (itemsControl.Items.Count > 0)
  311. {
  312. throw new InvalidOperationException("When using ItemsControlHelper.EnumValuesToItemsSource, Items Collection must be null");
  313. }
  314. var bindingExpression = BindingOperations.GetBindingExpression(itemsControl, Selector.SelectedItemProperty);
  315. if (bindingExpression == null)
  316. {
  317. throw new InvalidOperationException("ItemsControl must be binding SelectedItem property");
  318. }
  319. var binding = bindingExpression.ParentBinding;
  320. var dataType = bindingExpression.DataItem?.GetType();
  321. var paths = binding.Path.Path.Split('.');
  322. foreach (var path in paths)
  323. {
  324. var propertyInfo = dataType?.GetProperty(path);
  325. if (propertyInfo == null)
  326. {
  327. return;
  328. }
  329. dataType = propertyInfo.PropertyType;
  330. }
  331. if (dataType!=null&&!dataType.IsEnum)
  332. {
  333. var underlyingType = Nullable.GetUnderlyingType(dataType);
  334. if (underlyingType == null)
  335. {
  336. return;
  337. }
  338. dataType = underlyingType;
  339. }
  340. var itemsSourceBinding = new Binding();
  341. itemsSourceBinding.Source = Enum.GetValues(dataType);
  342. itemsSourceBinding.Mode = BindingMode.OneWay;
  343. itemsControl.SetBinding(ItemsControl.ItemsSourceProperty, itemsSourceBinding);
  344. }
  345. private static void ItemsControl_Loaded(object sender, RoutedEventArgs e)
  346. {
  347. var itemsControl = (ItemsControl)sender;
  348. itemsControl.Loaded -= ItemsControl_Loaded;
  349. SetItemsSource(itemsControl);
  350. }
  351. }
  352. }