DataGridCell.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // (c) Copyright Microsoft Corporation.
  2. // This source is subject to the Microsoft Public License (Ms-PL).
  3. // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
  4. // All other rights reserved.
  5. using Avalonia.Controls.Primitives;
  6. using Avalonia.Controls.Shapes;
  7. using Avalonia.Input;
  8. namespace Avalonia.Controls
  9. {
  10. /// <summary>
  11. /// Represents an individual <see cref="T:Avalonia.Controls.DataGrid" /> cell.
  12. /// </summary>
  13. public class DataGridCell : ContentControl
  14. {
  15. private const string DATAGRIDCELL_elementRightGridLine = "PART_RightGridLine";
  16. private Rectangle _rightGridLine;
  17. private DataGridColumn _owningColumn;
  18. bool _isValid;
  19. public static readonly DirectProperty<DataGridCell, bool> IsValidProperty =
  20. AvaloniaProperty.RegisterDirect<DataGridCell, bool>(
  21. nameof(IsValid),
  22. o => o.IsValid);
  23. static DataGridCell()
  24. {
  25. PointerPressedEvent.AddClassHandler<DataGridCell>(
  26. (x,e) => x.DataGridCell_PointerPressed(e), handledEventsToo: true);
  27. }
  28. public DataGridCell()
  29. { }
  30. public bool IsValid
  31. {
  32. get { return _isValid; }
  33. internal set { SetAndRaise(IsValidProperty, ref _isValid, value); }
  34. }
  35. internal DataGridColumn OwningColumn
  36. {
  37. get => _owningColumn;
  38. set
  39. {
  40. if (_owningColumn != value)
  41. {
  42. _owningColumn = value;
  43. OnOwningColumnSet(value);
  44. }
  45. }
  46. }
  47. internal DataGridRow OwningRow
  48. {
  49. get;
  50. set;
  51. }
  52. internal DataGrid OwningGrid
  53. {
  54. get { return OwningRow?.OwningGrid ?? OwningColumn?.OwningGrid; }
  55. }
  56. internal double ActualRightGridLineWidth
  57. {
  58. get { return _rightGridLine?.Bounds.Width ?? 0; }
  59. }
  60. internal int ColumnIndex
  61. {
  62. get { return OwningColumn?.Index ?? -1; }
  63. }
  64. internal int RowIndex
  65. {
  66. get { return OwningRow?.Index ?? -1; }
  67. }
  68. internal bool IsCurrent
  69. {
  70. get
  71. {
  72. return OwningGrid.CurrentColumnIndex == OwningColumn.Index &&
  73. OwningGrid.CurrentSlot == OwningRow.Slot;
  74. }
  75. }
  76. private bool IsEdited
  77. {
  78. get
  79. {
  80. return OwningGrid.EditingRow == OwningRow &&
  81. OwningGrid.EditingColumnIndex == ColumnIndex;
  82. }
  83. }
  84. private bool IsMouseOver
  85. {
  86. get
  87. {
  88. return OwningRow != null && OwningRow.MouseOverColumnIndex == ColumnIndex;
  89. }
  90. set
  91. {
  92. if (value != IsMouseOver)
  93. {
  94. if (value)
  95. {
  96. OwningRow.MouseOverColumnIndex = ColumnIndex;
  97. }
  98. else
  99. {
  100. OwningRow.MouseOverColumnIndex = null;
  101. }
  102. }
  103. }
  104. }
  105. /// <summary>
  106. /// Builds the visual tree for the cell control when a new template is applied.
  107. /// </summary>
  108. protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
  109. {
  110. base.OnTemplateApplied(e);
  111. UpdatePseudoClasses();
  112. _rightGridLine = e.NameScope.Find<Rectangle>(DATAGRIDCELL_elementRightGridLine);
  113. if (_rightGridLine != null && OwningColumn == null)
  114. {
  115. // Turn off the right GridLine for filler cells
  116. _rightGridLine.IsVisible = false;
  117. }
  118. else
  119. {
  120. EnsureGridLine(null);
  121. }
  122. }
  123. protected override void OnPointerEnter(PointerEventArgs e)
  124. {
  125. base.OnPointerEnter(e);
  126. if (OwningRow != null)
  127. {
  128. IsMouseOver = true;
  129. }
  130. }
  131. protected override void OnPointerLeave(PointerEventArgs e)
  132. {
  133. base.OnPointerLeave(e);
  134. if (OwningRow != null)
  135. {
  136. IsMouseOver = false;
  137. }
  138. }
  139. //TODO TabStop
  140. private void DataGridCell_PointerPressed(PointerPressedEventArgs e)
  141. {
  142. // OwningGrid is null for TopLeftHeaderCell and TopRightHeaderCell because they have no OwningRow
  143. if (OwningGrid != null)
  144. {
  145. OwningGrid.OnCellPointerPressed(new DataGridCellPointerPressedEventArgs(this, OwningRow, OwningColumn, e));
  146. if (e.MouseButton == MouseButton.Left)
  147. {
  148. if (!e.Handled)
  149. //if (!e.Handled && OwningGrid.IsTabStop)
  150. {
  151. OwningGrid.Focus();
  152. }
  153. if (OwningRow != null)
  154. {
  155. e.Handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, ColumnIndex, OwningRow.Slot, !e.Handled);
  156. OwningGrid.UpdatedStateOnMouseLeftButtonDown = true;
  157. }
  158. }
  159. }
  160. }
  161. internal void UpdatePseudoClasses()
  162. {
  163. }
  164. // Makes sure the right gridline has the proper stroke and visibility. If lastVisibleColumn is specified, the
  165. // right gridline will be collapsed if this cell belongs to the lastVisibileColumn and there is no filler column
  166. internal void EnsureGridLine(DataGridColumn lastVisibleColumn)
  167. {
  168. if (OwningGrid != null && _rightGridLine != null)
  169. {
  170. if (OwningGrid.VerticalGridLinesBrush != null && OwningGrid.VerticalGridLinesBrush != _rightGridLine.Fill)
  171. {
  172. _rightGridLine.Fill = OwningGrid.VerticalGridLinesBrush;
  173. }
  174. bool newVisibility =
  175. (OwningGrid.GridLinesVisibility == DataGridGridLinesVisibility.Vertical || OwningGrid.GridLinesVisibility == DataGridGridLinesVisibility.All)
  176. && (OwningGrid.ColumnsInternal.FillerColumn.IsActive || OwningColumn != lastVisibleColumn);
  177. if (newVisibility != _rightGridLine.IsVisible)
  178. {
  179. _rightGridLine.IsVisible = newVisibility;
  180. }
  181. }
  182. }
  183. private void OnOwningColumnSet(DataGridColumn column)
  184. {
  185. if (column == null)
  186. {
  187. Classes.Clear();
  188. }
  189. else
  190. {
  191. Classes.Replace(column.CellStyleClasses);
  192. }
  193. }
  194. }
  195. }