DynamicSplitPanel.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. using System;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using System.Windows.Data;
  5. using System.Windows.Input;
  6. using InABox.Core;
  7. using Syncfusion.Windows.Controls.Input;
  8. namespace InABox.DynamicGrid
  9. {
  10. public enum DynamicSplitPanelView
  11. {
  12. Master,
  13. Detail,
  14. Combined
  15. }
  16. public class DynamicSplitPanelChangedArgs : EventArgs
  17. {
  18. public DynamicSplitPanelView View { get; set; }
  19. public double MasterWidth { get; set; }
  20. public double DetailHeight { get; set; }
  21. }
  22. public delegate void DynamicSplitPanelChanged(object sender, DynamicSplitPanelChangedArgs e);
  23. public class DynamicSplitPanel : Control
  24. {
  25. public static readonly DependencyProperty ViewProperty = DependencyProperty.Register("View", typeof(DynamicSplitPanelView),
  26. typeof(DynamicSplitPanel), new UIPropertyMetadata(DynamicSplitPanelView.Detail));
  27. //public static readonly DependencyProperty HeaderVisibilityProperty = DependencyProperty.Register("HeaderVisibility", typeof(Visibility), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  28. //public Visibility HeaderVisibility
  29. //{
  30. // get { return (Visibility)GetValue(HeaderVisibilityProperty); }
  31. // set
  32. // {
  33. // SetValue(HeaderVisibilityProperty, value);
  34. // ConfigureScreen();
  35. // }
  36. //}
  37. public static readonly DependencyProperty MasterWidthProperty =
  38. DependencyProperty.Register("MasterWidth", typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)300F));
  39. public static readonly DependencyProperty MasterCaptionProperty =
  40. DependencyProperty.Register("MasterCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  41. public static readonly DependencyProperty DetailCaptionProperty =
  42. DependencyProperty.Register("DetailCaption", typeof(string), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  43. public static readonly DependencyProperty HeaderProperty =
  44. DependencyProperty.Register("Header", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  45. public static readonly DependencyProperty MasterProperty =
  46. DependencyProperty.Register("Master", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  47. public static readonly DependencyProperty DetailHeaderProperty =
  48. DependencyProperty.Register("DetailHeader", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  49. public static readonly DependencyProperty DetailProperty =
  50. DependencyProperty.Register("Detail", typeof(FrameworkElement), typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  51. public static readonly DependencyProperty DetailHeightProperty =
  52. DependencyProperty.Register("DetailHeight", typeof(double), typeof(DynamicSplitPanel), new UIPropertyMetadata((double)200F));
  53. public static readonly DependencyProperty SecondaryDetailProperty = DependencyProperty.Register("SecondaryDetail", typeof(FrameworkElement),
  54. typeof(DynamicSplitPanel), new UIPropertyMetadata(null));
  55. private Button CombinedLeft;
  56. private Button CombinedRight;
  57. private Grid DetailGrid;
  58. private Label DetailsHeader;
  59. private Button DetailsOnly;
  60. private SfGridSplitter DetailSplitter;
  61. private Grid Grid;
  62. private Label MasterHeader;
  63. private Button MasterOnly;
  64. private SfGridSplitter Splitter;
  65. static DynamicSplitPanel()
  66. {
  67. DefaultStyleKeyProperty.OverrideMetadata(typeof(DynamicSplitPanel), new FrameworkPropertyMetadata(typeof(DynamicSplitPanel)));
  68. }
  69. public DynamicSplitPanelView View
  70. {
  71. get => (DynamicSplitPanelView)GetValue(ViewProperty);
  72. set
  73. {
  74. SetValue(ViewProperty, value);
  75. ConfigureScreen();
  76. }
  77. }
  78. public double MasterWidth
  79. {
  80. get => (double)GetValue(MasterWidthProperty);
  81. set
  82. {
  83. SetValue(MasterWidthProperty, value);
  84. ConfigureScreen();
  85. }
  86. }
  87. public string MasterCaption
  88. {
  89. get => (string)GetValue(MasterCaptionProperty);
  90. set => SetValue(MasterCaptionProperty, value);
  91. //MasterHeader.Content = value;
  92. }
  93. public string DetailCaption
  94. {
  95. get => (string)GetValue(DetailCaptionProperty);
  96. set => SetValue(DetailCaptionProperty, value);
  97. //DetailHeader.Content = value;
  98. }
  99. public FrameworkElement Header
  100. {
  101. get => (FrameworkElement)GetValue(HeaderProperty);
  102. set => SetValue(HeaderProperty, value);
  103. }
  104. public FrameworkElement Master
  105. {
  106. get => (FrameworkElement)GetValue(MasterProperty);
  107. set => SetValue(MasterProperty, value);
  108. }
  109. public FrameworkElement DetailHeader
  110. {
  111. get => (FrameworkElement)GetValue(DetailHeaderProperty);
  112. set => SetValue(DetailHeaderProperty, value);
  113. }
  114. public FrameworkElement Detail
  115. {
  116. get => (FrameworkElement)GetValue(DetailProperty);
  117. set => SetValue(DetailProperty, value);
  118. }
  119. public double DetailHeight
  120. {
  121. get => (double)GetValue(DetailHeightProperty);
  122. set
  123. {
  124. SetValue(DetailHeightProperty, value);
  125. ConfigureScreen();
  126. }
  127. }
  128. public FrameworkElement SecondaryDetail
  129. {
  130. get => (FrameworkElement)GetValue(SecondaryDetailProperty);
  131. set => SetValue(SecondaryDetailProperty, value);
  132. }
  133. public event DynamicSplitPanelChanged OnChanged;
  134. private void RightClick(object sender, RoutedEventArgs e)
  135. {
  136. if (View == DynamicSplitPanelView.Detail)
  137. View = DynamicSplitPanelView.Combined;
  138. else if (View == DynamicSplitPanelView.Combined)
  139. View = DynamicSplitPanelView.Master;
  140. Changed();
  141. }
  142. private void LeftClick(object sender, RoutedEventArgs e)
  143. {
  144. if (View == DynamicSplitPanelView.Master)
  145. View = DynamicSplitPanelView.Combined;
  146. else if (View == DynamicSplitPanelView.Combined)
  147. View = DynamicSplitPanelView.Detail;
  148. Changed();
  149. }
  150. private void ConfigureScreen()
  151. {
  152. CheckParts();
  153. try
  154. {
  155. if (MasterHeader != null)
  156. MasterHeader.Content = MasterCaption;
  157. if (DetailsHeader != null)
  158. DetailsHeader.Content = DetailCaption;
  159. if (CombinedLeft != null)
  160. CombinedLeft.Visibility = View == DynamicSplitPanelView.Combined ? Visibility.Visible : Visibility.Collapsed;
  161. if (CombinedRight != null)
  162. CombinedRight.Visibility = View == DynamicSplitPanelView.Combined ? Visibility.Visible : Visibility.Collapsed;
  163. if (Grid != null)
  164. {
  165. Grid.ColumnDefinitions[0].Width = View == DynamicSplitPanelView.Detail && Master != null
  166. ? new GridLength(1.0F, GridUnitType.Auto)
  167. : new GridLength(0.0F, GridUnitType.Pixel);
  168. Grid.ColumnDefinitions[1].Width = Master == null ? new GridLength(0.0F, GridUnitType.Pixel) :
  169. View == DynamicSplitPanelView.Master ? new GridLength(1.0F, GridUnitType.Star) :
  170. View == DynamicSplitPanelView.Detail ? new GridLength(0.0F, GridUnitType.Pixel) :
  171. new GridLength(MasterWidth, GridUnitType.Pixel);
  172. Grid.ColumnDefinitions[2].Width = View == DynamicSplitPanelView.Combined && Master != null
  173. ? new GridLength(1.0F, GridUnitType.Auto)
  174. : new GridLength(0.0F, GridUnitType.Pixel);
  175. Grid.ColumnDefinitions[3].Width = View == DynamicSplitPanelView.Master
  176. ? new GridLength(0.0F, GridUnitType.Star)
  177. : new GridLength(1.0F, GridUnitType.Star);
  178. Grid.ColumnDefinitions[4].Width = View == DynamicSplitPanelView.Master
  179. ? new GridLength(1.0F, GridUnitType.Auto)
  180. : new GridLength(0.0F, GridUnitType.Pixel);
  181. Grid.RowDefinitions[0].Height =
  182. Header == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
  183. }
  184. if (DetailGrid != null)
  185. {
  186. DetailGrid.SetValue(Grid.RowProperty, DetailHeader == null ? 0 : 1);
  187. DetailGrid.SetValue(Grid.RowSpanProperty, DetailHeader == null ? 2 : 1);
  188. DetailGrid.RowDefinitions[0].Height = SecondaryDetail == null
  189. ? new GridLength(1.0F, GridUnitType.Star)
  190. : new GridLength(DetailHeight, GridUnitType.Pixel);
  191. DetailGrid.RowDefinitions[1].Height =
  192. SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Auto);
  193. DetailGrid.RowDefinitions[2].Height =
  194. SecondaryDetail == null ? new GridLength(0.0F, GridUnitType.Pixel) : new GridLength(1.0F, GridUnitType.Star);
  195. }
  196. }
  197. catch (Exception e)
  198. {
  199. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  200. }
  201. }
  202. private void Splitter_PreviewMouseUp(object sender, MouseButtonEventArgs e)
  203. {
  204. SetValue(MasterWidthProperty, Grid.ColumnDefinitions[1].ActualWidth);
  205. SetValue(DetailHeightProperty, SecondaryDetail == null ? 0.0F : DetailGrid.RowDefinitions[0].ActualHeight);
  206. Changed();
  207. }
  208. private void Changed()
  209. {
  210. OnChanged?.Invoke(this, new DynamicSplitPanelChangedArgs { View = View, MasterWidth = MasterWidth, DetailHeight = DetailHeight });
  211. }
  212. public override void OnApplyTemplate()
  213. {
  214. base.OnApplyTemplate();
  215. CheckParts();
  216. ConfigureScreen();
  217. }
  218. private void CheckParts()
  219. {
  220. try
  221. {
  222. if (Grid == null)
  223. Grid = GetTemplateChild("PART_Grid") as Grid;
  224. if (DetailGrid == null)
  225. DetailGrid = GetTemplateChild("PART_DetailGrid") as Grid;
  226. if (MasterHeader == null)
  227. MasterHeader = GetTemplateChild("PART_MasterHeader") as Label;
  228. if (DetailsHeader == null)
  229. DetailsHeader = GetTemplateChild("PART_DetailHeader") as Label;
  230. if (Splitter == null)
  231. {
  232. Splitter = GetTemplateChild("PART_Splitter") as SfGridSplitter;
  233. if (Splitter != null)
  234. {
  235. Splitter.PreviewMouseUp += Splitter_PreviewMouseUp;
  236. Splitter.TargetUpdated += Splitter_TargetUpdated;
  237. }
  238. }
  239. if (DetailSplitter == null)
  240. {
  241. DetailSplitter = GetTemplateChild("PART_DetailSplitter") as SfGridSplitter;
  242. if (DetailSplitter != null)
  243. DetailSplitter.PreviewMouseUp += Splitter_PreviewMouseUp;
  244. }
  245. if (DetailsOnly == null)
  246. {
  247. DetailsOnly = GetTemplateChild("PART_DetailsOnly") as Button;
  248. if (DetailsOnly != null)
  249. DetailsOnly.Click += RightClick;
  250. }
  251. if (CombinedRight == null)
  252. {
  253. CombinedRight = GetTemplateChild("PART_CombinedRight") as Button;
  254. if (CombinedRight != null)
  255. CombinedRight.Click += RightClick;
  256. }
  257. if (CombinedLeft == null)
  258. {
  259. CombinedLeft = GetTemplateChild("PART_CombinedLeft") as Button;
  260. if (CombinedLeft != null)
  261. CombinedLeft.Click += LeftClick;
  262. }
  263. if (MasterOnly == null)
  264. {
  265. MasterOnly = GetTemplateChild("PART_MasterOnly") as Button;
  266. if (MasterOnly != null)
  267. MasterOnly.Click += LeftClick;
  268. }
  269. }
  270. catch (Exception e)
  271. {
  272. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  273. }
  274. }
  275. private void Splitter_TargetUpdated(object sender, DataTransferEventArgs e)
  276. {
  277. //
  278. }
  279. }
  280. }