RecipeEditorControl.xaml.cs 11 KB

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