OptionalUniformGrid.xaml.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 NEIntelligentControl2.Views.Basic
  16. {
  17. /// <summary>
  18. /// 可框选的UniformGrid
  19. /// </summary>
  20. public partial class OptionalUniformGrid : UserControl
  21. {
  22. // ----------依赖项属性-------------
  23. public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(int), typeof(OptionalUniformGrid));
  24. /// <summary>
  25. /// 获取或设置网格中的列数
  26. /// </summary>
  27. public int Columns { get => (int)GetValue(ColumnsProperty); set => SetValue(ColumnsProperty, value); }
  28. /// <summary>
  29. /// 获取子元素
  30. /// </summary>
  31. public UIElementCollection Children { get => _UGMain.Children; }
  32. private IOptional _CurrentSelected; // 当前选中的卡片
  33. private List<IOptional> _Optionals; // 控件集合
  34. private Point _StartPoint; // 开始框选鼠标位置
  35. private int _MoveTimes; // 移动次数
  36. public OptionalUniformGrid()
  37. {
  38. InitializeComponent();
  39. _Optionals = new List<IOptional>();
  40. }
  41. public void Add(UIElement element)
  42. {
  43. _UGMain.Children.Add(element);
  44. var v = element as IOptional;
  45. if (v == null) return;
  46. _Optionals.Add(v);
  47. v.SelectedChanged += ItemSelectedChanged;
  48. if (_CurrentSelected == null)
  49. _CurrentSelected = v;
  50. }
  51. internal void Remove(UIElement ue)
  52. {
  53. if (ue == null) return;
  54. var v = ue as IOptional;
  55. if (v != null)
  56. {
  57. _Optionals.Remove(v);
  58. }
  59. _UGMain.Children.Remove(ue);
  60. }
  61. private void ItemSelectedChanged(IOptional sender, bool isMultiSelect)
  62. {
  63. if (isMultiSelect)
  64. {
  65. SelectAll(sender);
  66. }
  67. else
  68. {
  69. _CurrentSelected = sender;
  70. sender.IsSelected = !sender.IsSelected;
  71. }
  72. }
  73. private void SelectAll(IOptional sender)
  74. {
  75. int index1 = _Optionals.IndexOf(_CurrentSelected);
  76. int index2 = _Optionals.IndexOf(sender);
  77. if (index1 > index2)
  78. {
  79. int i = index1;
  80. index1 = index2;
  81. index2 = i;
  82. }
  83. for (int i = 0; i < _Optionals.Count; ++i)
  84. {
  85. bool b = i >= index1 && i <= index2;
  86. _Optionals[i].IsSelected = b;
  87. }
  88. }
  89. private void Grid_MouseMove(object sender, MouseEventArgs e)
  90. {
  91. if (e.LeftButton != MouseButtonState.Pressed) return;
  92. ++_MoveTimes;
  93. if (_MoveTimes < 2) return;
  94. var ct = sender as Grid;
  95. if (ct == null) return;
  96. if (_RTMain.Visibility != Visibility.Visible)
  97. {
  98. _RTMain.Visibility = Visibility.Visible;
  99. }
  100. var ponit = e.GetPosition(ct);
  101. Point p1 = new Point();
  102. p1.X = _StartPoint.X < ponit.X ? _StartPoint.X : ponit.X;
  103. p1.Y = _StartPoint.Y < ponit.Y ? _StartPoint.Y : ponit.Y;
  104. Point p2 = new Point();
  105. p2.X = _StartPoint.X > ponit.X ? _StartPoint.X : ponit.X;
  106. p2.Y = _StartPoint.Y > ponit.Y ? _StartPoint.Y : ponit.Y;
  107. _RTMain.Margin = new Thickness(p1.X, p1.Y, ct.ActualWidth - p2.X, ct.ActualHeight - p2.Y);
  108. CheckSelected(new Rect(p1, p2));
  109. }
  110. private void CheckSelected(Rect rect)
  111. {
  112. var pt = new Point();
  113. foreach (var v in _UGMain.Children)
  114. {
  115. var o = v as IOptional;
  116. var ct = v as Control;
  117. if (o == null || ct == null) continue;
  118. var tt = ct.TransformToAncestor(_UGMain).Transform(pt);
  119. Rect rt = new Rect(tt.X, tt.Y, ct.ActualWidth, ct.ActualHeight);
  120. var b = rect.IntersectsWith(rt);
  121. if (Keyboard.Modifiers == ModifierKeys.Control)
  122. {
  123. if (b) o.IsSelected = true;
  124. }
  125. else
  126. {
  127. o.IsSelected = b;
  128. }
  129. }
  130. }
  131. private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  132. {
  133. var ct = sender as Grid;
  134. if (ct == null) return;
  135. _StartPoint = e.GetPosition(ct);
  136. }
  137. private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  138. {
  139. _MoveTimes = 0;
  140. _RTMain.Visibility = Visibility.Collapsed;
  141. if (sender != e.OriginalSource) return;
  142. foreach (var v in _UGMain.Children)
  143. {
  144. (v as IOptional).IsSelected = false;
  145. }
  146. }
  147. private void Grid_MouseLeave(object sender, MouseEventArgs e)
  148. {
  149. _MoveTimes = 0;
  150. _RTMain.Visibility = Visibility.Collapsed;
  151. if (e.LeftButton != MouseButtonState.Pressed) return;
  152. foreach (var v in _Optionals)
  153. {
  154. v.IsSelected = false;
  155. }
  156. }
  157. internal void Clear()
  158. {
  159. _UGMain.Children.Clear();
  160. _Optionals.Clear();
  161. }
  162. }
  163. /// <summary>
  164. /// 可选择的
  165. /// </summary>
  166. public interface IOptional
  167. {
  168. /// <summary>
  169. /// 是否被选中
  170. /// </summary>
  171. bool IsSelected { get; set; }
  172. /// <summary>
  173. /// 选择改变事件
  174. /// </summary>
  175. event SelectedEventHandler SelectedChanged;
  176. }
  177. /// <summary>
  178. /// 卡片被选择事件
  179. /// </summary>
  180. /// <param name="sender">发送者</param>
  181. /// <param name="isMultiSelect">是否多选</param>
  182. public delegate void SelectedEventHandler(IOptional sender, bool isMultiSelect);
  183. }