PageRenderTime 31ms CodeModel.GetById 3ms RepoModel.GetById 1ms app.codeStats 1ms

/class/Microsoft.SilverlightControls/SDKControls/Data/src/DataGrid/DataGrid.xaml.cs

http://github.com/mono/moon
C# | 6063 lines | 4566 code | 784 blank | 713 comment | 1160 complexity | ed3fbb8e759d43c44a097ec2760d700b MD5 | raw file
Possible License(s): CC-BY-SA-3.0, MIT, LGPL-2.1, MPL-2.0-no-copyleft-exception, GPL-3.0

Large files files are truncated, but you can click here to view the full file

  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 System.Collections;
  6. using System.Collections.Generic;
  7. using System.Collections.ObjectModel;
  8. using System.Diagnostics;
  9. using System.Diagnostics.CodeAnalysis;
  10. using System.Windows.Automation.Peers;
  11. using System.Windows.Controls.Primitives;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. namespace System.Windows.Controls
  15. {
  16. [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")]
  17. /// <summary>
  18. /// Displays data in a customizable grid.
  19. /// </summary>
  20. [TemplatePart(Name = DataGrid.DATAGRID_elementRowsPresenterName, Type = typeof(DataGridRowsPresenter))]
  21. [TemplatePart(Name = DataGrid.DATAGRID_elementColumnHeadersPresenterName, Type = typeof(DataGridColumnHeadersPresenter))]
  22. [TemplatePart(Name = DataGrid.DATAGRID_elementFrozenColumnScrollBarSpacerName, Type = typeof(FrameworkElement))]
  23. [TemplatePart(Name = DataGrid.DATAGRID_elementHorizontalScrollbarName, Type = typeof(ScrollBar))]
  24. [TemplatePart(Name = DataGrid.DATAGRID_elementVerticalScrollbarName, Type = typeof(ScrollBar))]
  25. public partial class DataGrid : Control
  26. {
  27. #region Constants
  28. private const string DATAGRID_elementRowsPresenterName = "RowsPresenter";
  29. private const string DATAGRID_elementColumnHeadersPresenterName = "ColumnHeadersPresenter";
  30. private const string DATAGRID_elementFrozenColumnScrollBarSpacerName = "FrozenColumnScrollBarSpacer";
  31. private const string DATAGRID_elementHorizontalScrollbarName = "HorizontalScrollbar";
  32. private const string DATAGRID_elementRowHeadersPresenterName = "RowHeadersPresenter";
  33. private const string DATAGRID_elementTopLeftCornerHeaderName = "TopLeftCornerHeader";
  34. private const string DATAGRID_elementTopRightCornerHeaderName = "TopRightCornerHeader";
  35. private const string DATAGRID_elementVerticalScrollbarName = "VerticalScrollbar";
  36. private const bool DATAGRID_defaultAutoGenerateColumns = true;
  37. internal const bool DATAGRID_defaultCanUserReorderColumns = true;
  38. internal const bool DATAGRID_defaultCanUserResizeColumns = true;
  39. internal const bool DATAGRID_defaultCanUserSortColumns = true;
  40. private const DataGridRowDetailsVisibilityMode DATAGRID_defaultRowDetailsVisibility = DataGridRowDetailsVisibilityMode.VisibleWhenSelected;
  41. private const DataGridSelectionMode DATAGRID_defaultSelectionMode = DataGridSelectionMode.Extended;
  42. private const double DATAGRID_horizontalGridLinesThickness = 1;
  43. private const double DATAGRID_minimumRowHeaderWidth = 4;
  44. private const double DATAGRID_minimumColumnHeaderHeight = 4;
  45. private const double DATAGRID_maxHeadersThickness = 32768;
  46. private const double DATAGRID_defaultRowHeight = 22;
  47. private const double DATAGRID_defaultMinColumnWidth = 20;
  48. private const double DATAGRID_defaultMaxColumnWidth = double.PositiveInfinity;
  49. #endregion Constants
  50. #region Data
  51. // DataGrid Template Parts
  52. private DataGridRowsPresenter _rowsPresenter;
  53. private DataGridColumnHeadersPresenter _columnHeadersPresenter;
  54. private ScrollBar _hScrollBar;
  55. private ScrollBar _vScrollBar;
  56. private List<object> _addedSelectedItems;
  57. private byte _autoGeneratingColumnOperationCount;
  58. private Popup _columnDropLocationIndicatorPopup;
  59. private Control _columnDropLocationIndicator;
  60. private DataGridCellCoordinates _currentCellCoordinates;
  61. private List<DataGridCell> _editingBoundCells;
  62. private int _editingElementGotFocusListeners;
  63. private int _editingElementLostFocusListeners; // Number of subscribers for the LostFocus event of the element of a edited cell in a column
  64. private int _editingColumnIndex;
  65. private DataGridRow _editingRow;
  66. private RoutedEventArgs _editingEventArgs;
  67. private Control _editingTemplateControl; // Control that has focus inside a template column
  68. private bool _focusEditingControl;
  69. private DataGridRow _focusedRow;
  70. private FrameworkElement _frozenColumnScrollBarSpacer;
  71. // the sum of the widths in pixels of the scrolling columns preceding
  72. // the first displayed scrolling column
  73. private double _horizontalOffset;
  74. private bool _ignoreNextScrollBarsLayout;
  75. private byte _horizontalScrollChangesIgnored;
  76. // Nth row of rows 0..N that make up the RowHeightEstimate
  77. private int _lastEstimatedRow;
  78. private List<DataGridRow> _loadedRows;
  79. // prevents reentry into the VerticalScroll event handler
  80. private bool _makeFirstDisplayedCellCurrentCellPending;
  81. private bool _measured;
  82. private int? _mouseOverRowIndex; // -1 is used for the 'new row'
  83. // the number of pixels of the firstDisplayedScrollingCol which are not displayed
  84. private double _negHorizontalOffset;
  85. // the number of pixels of DisplayData.FirstDisplayedScrollingRow which are not displayed
  86. //
  87. private int _noSelectionChangeCount;
  88. private List<object> _removedSelectedItems;
  89. private double _rowHeaderDesiredWidth;
  90. private DataGridSelectedItemsCollection _selectedItems;
  91. private bool _selectionChanged;
  92. private IndexToValueTable<Visibility> _showDetailsTable;
  93. private bool _temporarilyResetCurrentCell;
  94. private ContentControl _topLeftCornerHeader;
  95. private ContentControl _topRightCornerHeader;
  96. private object _uneditedValue; // Represents the original current cell value at the time it enters editing mode.
  97. private byte _verticalScrollChangesIgnored;
  98. // An approximation of the sum of the heights in pixels of the scrolling rows preceding
  99. // the first displayed scrolling row. Since the scrolled off rows are discarded, the grid
  100. // does not know their actual height. The heights used for the approximation are the ones
  101. // set as the rows were scrolled off.
  102. private double _verticalOffset;
  103. #endregion Data
  104. #region Events
  105. public event EventHandler<DataGridAutoGeneratingColumnEventArgs> AutoGeneratingColumn;
  106. public event EventHandler<DataGridBeginningEditEventArgs> BeginningEdit;
  107. //
  108. public event EventHandler<DataGridColumnEventArgs> ColumnDisplayIndexChanged;
  109. public event EventHandler<DragStartedEventArgs> ColumnHeaderDragStarted;
  110. public event EventHandler<DragDeltaEventArgs> ColumnHeaderDragDelta;
  111. public event EventHandler<DragCompletedEventArgs> ColumnHeaderDragCompleted;
  112. /// <summary>
  113. /// Raised when column reordering ends, to allow subscribers to clean up.
  114. /// </summary>
  115. public event EventHandler<DataGridColumnEventArgs> ColumnReordered;
  116. /// <summary>
  117. /// Raised when starting a column reordering action. Subscribers to this event can
  118. /// set tooltip and caret UIElements, constrain tooltip position, indicate that
  119. /// a preview should be shown, or cancel reordering.
  120. /// </summary>
  121. public event EventHandler<DataGridColumnReorderingEventArgs> ColumnReordering;
  122. //
  123. public event EventHandler<EventArgs> CurrentCellChanged;
  124. public event EventHandler<DataGridPreparingCellForEditEventArgs> PreparingCellForEdit;
  125. public event EventHandler<DataGridRowEventArgs> LoadingRow;
  126. public event EventHandler<DataGridRowDetailsEventArgs> LoadingRowDetails;
  127. public event EventHandler<DataGridRowEventArgs> UnloadingRow;
  128. public event EventHandler<DataGridRowDetailsEventArgs> UnloadingRowDetails;
  129. public event EventHandler<DataGridRowDetailsEventArgs> RowDetailsVisibilityChanged;
  130. public event SelectionChangedEventHandler SelectionChanged;
  131. #endregion Events
  132. /// <summary>
  133. /// Initializes a new instance of the DataGrid class.
  134. /// </summary>
  135. [SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Justification="_minRowHeight should be 0.")]
  136. public DataGrid()
  137. {
  138. this.TabNavigation = KeyboardNavigationMode.Once;
  139. this.KeyDown += new KeyEventHandler(DataGrid_KeyDown);
  140. this.KeyUp += new KeyEventHandler(DataGrid_KeyUp);
  141. this.GotFocus += new RoutedEventHandler(DataGrid_GotFocus);
  142. this.LostFocus += new RoutedEventHandler(DataGrid_LostFocus);
  143. this._loadedRows = new List<DataGridRow>();
  144. this._editingBoundCells = new List<DataGridCell>(2);
  145. this._selectedItems = new DataGridSelectedItemsCollection(this);
  146. this.SetValueNoCallback(SelectedIndexProperty, -1);
  147. this.DisplayData = new DataGridDisplayData();
  148. this.ColumnsInternal = CreateColumnsInstance();
  149. this.SetValueNoCallback(ColumnWidthProperty, DataGridLength.Auto);
  150. this.SetValueNoCallback(MaxColumnWidthProperty, DATAGRID_defaultMaxColumnWidth);
  151. this.SetValueNoCallback(MinColumnWidthProperty, DATAGRID_defaultMinColumnWidth);
  152. this.SetValueNoCallback(RowHeightProperty, double.NaN);
  153. this.RowHeightEstimate = DATAGRID_defaultRowHeight;
  154. this.RowDetailsHeightEstimate = 0;
  155. this._rowHeaderDesiredWidth = 0;
  156. this.DataConnection = new DataGridDataConnection(this);
  157. //this._newRowLocation = DataGridNewRowLocation.Inline;
  158. this._showDetailsTable = new IndexToValueTable<Visibility>();
  159. this.AnchorRowIndex = -1;
  160. this._lastEstimatedRow = -1;
  161. this._editingColumnIndex = -1;
  162. this._mouseOverRowIndex = null;
  163. this.CurrentCellCoordinates = new DataGridCellCoordinates(-1, -1);
  164. this.SetValueNoCallback(RowHeaderWidthProperty, double.NaN);
  165. this.SetValueNoCallback(ColumnHeaderHeightProperty, double.NaN);
  166. this._addedSelectedItems = new List<object>();
  167. this._removedSelectedItems = new List<object>();
  168. DefaultStyleKey = typeof(DataGrid);
  169. }
  170. #region Dependency Properties
  171. #region AlternatingRowBackground
  172. /// <summary>
  173. /// Gets or sets a brush that describes the background of odd-numbered rows in the grid.
  174. /// </summary>
  175. public Brush AlternatingRowBackground
  176. {
  177. get { return GetValue(AlternatingRowBackgroundProperty) as Brush; }
  178. set { SetValue(AlternatingRowBackgroundProperty, value); }
  179. }
  180. /// <summary>
  181. /// Identifies the AlternatingRowBackground dependency property.
  182. /// </summary>
  183. public static readonly DependencyProperty AlternatingRowBackgroundProperty =
  184. DependencyProperty.Register(
  185. "AlternatingRowBackground",
  186. typeof(Brush),
  187. typeof(DataGrid),
  188. new PropertyMetadata(OnAlternatingRowBackgroundPropertyChanged));
  189. private static void OnAlternatingRowBackgroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  190. {
  191. DataGrid dataGrid = (DataGrid)d;
  192. if (dataGrid._rowsPresenter != null)
  193. {
  194. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  195. {
  196. row.EnsureBackground();
  197. }
  198. }
  199. }
  200. #endregion AlternatingRowBackground
  201. #region AreRowDetailsFrozen
  202. /// <summary>
  203. /// Gets or sets a value indicating whether the horizontal ScrollBar of the DataGrid affects the
  204. /// details section of a row.
  205. /// </summary>
  206. public bool AreRowDetailsFrozen
  207. {
  208. get { return (bool)GetValue(AreRowDetailsFrozenProperty); }
  209. set { SetValue(AreRowDetailsFrozenProperty, value); }
  210. }
  211. /// <summary>
  212. /// Identifies the AreRowDetailsFrozen dependency property.
  213. /// </summary>
  214. public static readonly DependencyProperty AreRowDetailsFrozenProperty =
  215. DependencyProperty.Register(
  216. "AreRowDetailsFrozen",
  217. typeof(bool),
  218. typeof(DataGrid),
  219. null);
  220. #endregion AreRowDetailsFrozen
  221. #region AutoGenerateColumns
  222. /// <summary>
  223. /// Gets or sets a value indicating whether columns are created automatically when the ItemsSource
  224. /// property is set.
  225. /// </summary>
  226. public bool AutoGenerateColumns
  227. {
  228. get { return (bool)GetValue(AutoGenerateColumnsProperty); }
  229. set { SetValue(AutoGenerateColumnsProperty, value); }
  230. }
  231. /// <summary>
  232. /// Identifies the AutoGenerateColumns dependency property.
  233. /// </summary>
  234. public static readonly DependencyProperty AutoGenerateColumnsProperty =
  235. DependencyProperty.Register(
  236. "AutoGenerateColumns",
  237. typeof(bool),
  238. typeof(DataGrid),
  239. new PropertyMetadata(OnAutoGenerateColumnsPropertyChanged));
  240. private static void OnAutoGenerateColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  241. {
  242. DataGrid dataGrid = (DataGrid)d;
  243. bool value = (bool)e.NewValue;
  244. if (value)
  245. {
  246. dataGrid.RefreshRowsAndColumns();
  247. }
  248. else
  249. {
  250. dataGrid.RemoveAutoGeneratedColumns();
  251. }
  252. }
  253. #endregion AutoGenerateColumns
  254. #region CanUserReorderColumns
  255. /// <summary>
  256. /// Gets or sets a value indicating whether users can reorder columns.
  257. /// </summary>
  258. public bool CanUserReorderColumns
  259. {
  260. get { return (bool)GetValue(CanUserReorderColumnsProperty); }
  261. set { SetValue(CanUserReorderColumnsProperty, value); }
  262. }
  263. /// <summary>
  264. /// Identifies the CanUserReorderColumns dependency property.
  265. /// </summary>
  266. public static readonly DependencyProperty CanUserReorderColumnsProperty =
  267. DependencyProperty.Register(
  268. "CanUserReorderColumns",
  269. typeof(bool),
  270. typeof(DataGrid),
  271. null);
  272. #endregion CanUserReorderColumns
  273. #region CanUserResizeColumns
  274. /// <summary>
  275. /// Gets or sets a value indicating whether users can resize columns.
  276. /// </summary>
  277. public bool CanUserResizeColumns
  278. {
  279. get { return (bool)GetValue(CanUserResizeColumnsProperty); }
  280. set { SetValue(CanUserResizeColumnsProperty, value); }
  281. }
  282. /// <summary>
  283. /// Identifies the CanUserResizeColumns dependency property.
  284. /// </summary>
  285. public static readonly DependencyProperty CanUserResizeColumnsProperty =
  286. DependencyProperty.Register(
  287. "CanUserResizeColumns",
  288. typeof(bool),
  289. typeof(DataGrid),
  290. null);
  291. #endregion CanUserResizeColumns
  292. #region CanUserSortColumns
  293. /// <summary>
  294. /// Gets or sets a value indicating whether users can sort columns.
  295. /// </summary>
  296. public bool CanUserSortColumns
  297. {
  298. get { return (bool)GetValue(CanUserSortColumnsProperty); }
  299. set { SetValue(CanUserSortColumnsProperty, value); }
  300. }
  301. /// <summary>
  302. /// Identifies the CanUserSortColumns dependency property.
  303. /// </summary>
  304. public static readonly DependencyProperty CanUserSortColumnsProperty =
  305. DependencyProperty.Register(
  306. "CanUserSortColumns",
  307. typeof(bool),
  308. typeof(DataGrid),
  309. null);
  310. #endregion CanUserSortColumns
  311. #region CellStyle
  312. /// <summary>
  313. /// Gets or sets the style used by cells when they are rendered.
  314. /// </summary>
  315. public Style CellStyle
  316. {
  317. get { return GetValue(CellStyleProperty) as Style; }
  318. set { SetValue(CellStyleProperty, value); }
  319. }
  320. public static readonly DependencyProperty CellStyleProperty =
  321. DependencyProperty.Register(
  322. "CellStyle",
  323. typeof(Style),
  324. typeof(DataGrid),
  325. new PropertyMetadata(OnCellStylePropertyChanged));
  326. private static void OnCellStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  327. {
  328. Style newStyle = e.NewValue as Style;
  329. if (newStyle != null)
  330. {
  331. DataGrid dataGrid = d as DataGrid;
  332. if (dataGrid != null && dataGrid._rowsPresenter != null)
  333. {
  334. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  335. {
  336. foreach (DataGridCell cell in row.Cells)
  337. {
  338. cell.EnsureCellStyle();
  339. }
  340. }
  341. dataGrid.InvalidateRowHeightEstimate();
  342. }
  343. }
  344. }
  345. #endregion CellStyle
  346. #region ColumnHeaderHeight
  347. /// <summary>
  348. /// Gets or sets the suggested height of the grid's column headers.
  349. /// </summary>
  350. public double ColumnHeaderHeight
  351. {
  352. get { return (double)GetValue(ColumnHeaderHeightProperty); }
  353. set { SetValue(ColumnHeaderHeightProperty, value); }
  354. }
  355. /// <summary>
  356. /// Identifies the ColumnHeaderHeight dependency property.
  357. /// </summary>
  358. public static readonly DependencyProperty ColumnHeaderHeightProperty =
  359. DependencyProperty.Register(
  360. "ColumnHeaderHeight",
  361. typeof(double),
  362. typeof(DataGrid),
  363. new PropertyMetadata(OnColumnHeaderHeightPropertyChanged));
  364. /// <summary>
  365. /// ColumnHeaderHeightProperty property changed handler.
  366. /// </summary>
  367. /// <param name="d">DataGrid that changed its ColumnHeaderHeight.</param>
  368. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  369. private static void OnColumnHeaderHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  370. {
  371. DataGrid dataGrid = (DataGrid)d;
  372. if (!dataGrid.IsHandlerSuspended(e.Property))
  373. {
  374. double value = (double)e.NewValue;
  375. if (value < DATAGRID_minimumColumnHeaderHeight)
  376. {
  377. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  378. throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("value", "ColumnHeaderHeight", DATAGRID_minimumColumnHeaderHeight);
  379. }
  380. if (value > DATAGRID_maxHeadersThickness)
  381. {
  382. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  383. throw DataGridError.DataGrid.ValueMustBeLessThanOrEqualTo("value", "ColumnHeaderHeight", DATAGRID_maxHeadersThickness);
  384. }
  385. dataGrid.InvalidateMeasure();
  386. }
  387. }
  388. #endregion ColumnHeaderHeight
  389. #region ColumnHeaderStyle
  390. /// <summary>
  391. /// Gets or sets the style used by column headers when they are rendered.
  392. /// </summary>
  393. public Style ColumnHeaderStyle
  394. {
  395. get { return GetValue(ColumnHeaderStyleProperty) as Style; }
  396. set { SetValue(ColumnHeaderStyleProperty, value); }
  397. }
  398. /// <summary>
  399. /// Identifies the ColumnHeaderStyle dependency property.
  400. /// </summary>
  401. public static readonly DependencyProperty ColumnHeaderStyleProperty = DependencyProperty.Register("ColumnHeaderStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(OnColumnHeaderStylePropertyChanged));
  402. private static void OnColumnHeaderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  403. {
  404. //
  405. Style newStyle = e.NewValue as Style;
  406. if (newStyle != null)
  407. {
  408. DataGrid dataGrid = d as DataGrid;
  409. if (dataGrid != null)
  410. {
  411. Style oldStyle = e.OldValue as Style;
  412. foreach (DataGridColumn column in dataGrid.Columns)
  413. {
  414. EnsureColumnHeaderCellStyle(column, oldStyle, newStyle);
  415. }
  416. EnsureColumnHeaderCellStyle(dataGrid.ColumnsInternal.FillerColumn, oldStyle, newStyle);
  417. }
  418. }
  419. }
  420. #endregion ColumnHeaderStyle
  421. #region ColumnWidth
  422. /// <summary>
  423. /// Gets or sets the width of the grid's columns.
  424. /// </summary>
  425. public DataGridLength ColumnWidth
  426. {
  427. get { return (DataGridLength)GetValue(ColumnWidthProperty); }
  428. set { SetValue(ColumnWidthProperty, value); }
  429. }
  430. /// <summary>
  431. /// Identifies the ColumnWidth dependency property.
  432. /// </summary>
  433. public static readonly DependencyProperty ColumnWidthProperty =
  434. DependencyProperty.Register(
  435. "ColumnWidth",
  436. typeof(DataGridLength),
  437. typeof(DataGrid),
  438. new PropertyMetadata(OnColumnWidthPropertyChanged));
  439. /// <summary>
  440. /// ColumnWidthProperty property changed handler.
  441. /// </summary>
  442. /// <param name="d">DataGrid that changed its ColumnWidth.</param>
  443. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  444. private static void OnColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  445. {
  446. DataGrid dataGrid = (DataGrid)d;
  447. dataGrid.EnsureHorizontalLayout();
  448. }
  449. #endregion ColumnWidth
  450. #region DragIndicatorStyle
  451. /// <summary>
  452. /// Gets or sets the style used by rows when they are rendered.
  453. /// </summary>
  454. public Style DragIndicatorStyle
  455. {
  456. get { return GetValue(DragIndicatorStyleProperty) as Style; }
  457. set { SetValue(DragIndicatorStyleProperty, value); }
  458. }
  459. public static readonly DependencyProperty DragIndicatorStyleProperty =
  460. DependencyProperty.Register(
  461. "DragIndicatorStyle",
  462. typeof(Style),
  463. typeof(DataGrid),
  464. null);
  465. #endregion DragIndicatorStyle
  466. #region DropLocationIndicatorStyle
  467. /// <summary>
  468. /// Gets or sets the style used by rows when they are rendered.
  469. /// </summary>
  470. public Style DropLocationIndicatorStyle
  471. {
  472. get { return GetValue(DropLocationIndicatorStyleProperty) as Style; }
  473. set { SetValue(DropLocationIndicatorStyleProperty, value); }
  474. }
  475. public static readonly DependencyProperty DropLocationIndicatorStyleProperty =
  476. DependencyProperty.Register(
  477. "DropLocationIndicatorStyle",
  478. typeof(Style),
  479. typeof(DataGrid),
  480. null);
  481. #endregion DropLocationIndicatorStyle
  482. #region FrozenColumnCount
  483. public int FrozenColumnCount
  484. {
  485. get { return (int)GetValue(FrozenColumnCountProperty); }
  486. set { SetValue(FrozenColumnCountProperty, value); }
  487. }
  488. public static readonly DependencyProperty FrozenColumnCountProperty =
  489. DependencyProperty.Register(
  490. "FrozenColumnCount",
  491. typeof(int),
  492. typeof(DataGrid),
  493. new PropertyMetadata(OnFrozenColumnCountPropertyChanged));
  494. private static void OnFrozenColumnCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  495. {
  496. ProcessFrozenColumnCount((DataGrid)d);
  497. }
  498. private static void ProcessFrozenColumnCount(DataGrid dataGrid)
  499. {
  500. dataGrid.CorrectColumnFrozenStates();
  501. dataGrid.ComputeScrollBarsLayout();
  502. dataGrid.InvalidateColumnHeadersArrange();
  503. dataGrid.InvalidateCellsArrange();
  504. }
  505. #endregion FrozenColumnCount
  506. #region GridLinesVisibility
  507. /// <summary>
  508. /// Gets or sets a value that indicates whether horizontal or vertical gridlines for
  509. /// the inner cells should be displayed.
  510. /// </summary>
  511. public DataGridGridLinesVisibility GridLinesVisibility
  512. {
  513. get { return (DataGridGridLinesVisibility)GetValue(GridLinesVisibilityProperty); }
  514. set { SetValue(GridLinesVisibilityProperty, value); }
  515. }
  516. /// <summary>
  517. /// Identifies the GridLines dependency property.
  518. /// </summary>
  519. public static readonly DependencyProperty GridLinesVisibilityProperty =
  520. DependencyProperty.Register(
  521. "GridLinesVisibility",
  522. typeof(DataGridGridLinesVisibility),
  523. typeof(DataGrid),
  524. new PropertyMetadata(OnGridLinesVisibilityPropertyChanged));
  525. /// <summary>
  526. /// GridLinesProperty property changed handler.
  527. /// </summary>
  528. /// <param name="d">DataGrid that changed its GridLines.</param>
  529. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  530. private static void OnGridLinesVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  531. {
  532. DataGrid dataGrid = (DataGrid)d;
  533. if (!dataGrid.IsHandlerSuspended(e.Property) && dataGrid._rowsPresenter != null)
  534. {
  535. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  536. {
  537. row.EnsureGridLines();
  538. row.InvalidateHorizontalArrange();
  539. }
  540. }
  541. }
  542. #endregion GridLinesVisibility
  543. #region HeadersVisibility
  544. /// <summary>
  545. /// Gets or sets a value that indicates whether column or row headers should be displayed.
  546. /// </summary>
  547. public DataGridHeadersVisibility HeadersVisibility
  548. {
  549. get { return (DataGridHeadersVisibility)GetValue(HeadersVisibilityProperty); }
  550. set { SetValue(HeadersVisibilityProperty, value); }
  551. }
  552. /// <summary>
  553. /// Identifies the HeadersVisibility dependency property.
  554. /// </summary>
  555. public static readonly DependencyProperty HeadersVisibilityProperty =
  556. DependencyProperty.Register(
  557. "HeadersVisibility",
  558. typeof(DataGridHeadersVisibility),
  559. typeof(DataGrid),
  560. new PropertyMetadata(OnHeadersVisibilityPropertyChanged));
  561. /// <summary>
  562. /// HeadersVisibilityProperty property changed handler.
  563. /// </summary>
  564. /// <param name="d">DataGrid that changed its HeadersVisibility.</param>
  565. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  566. private static void OnHeadersVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  567. {
  568. DataGrid dataGrid = (DataGrid)d;
  569. if (!dataGrid.IsHandlerSuspended(e.Property))
  570. {
  571. DataGridHeadersVisibility newValue = (DataGridHeadersVisibility)e.NewValue;
  572. DataGridHeadersVisibility oldValue = (DataGridHeadersVisibility)e.OldValue;
  573. Func<DataGridHeadersVisibility, DataGridHeadersVisibility, bool> hasFlags = (DataGridHeadersVisibility value, DataGridHeadersVisibility flags) => ((value & flags) == flags);
  574. bool newValueCols = hasFlags(newValue, DataGridHeadersVisibility.Column);
  575. bool newValueRows = hasFlags(newValue, DataGridHeadersVisibility.Row);
  576. bool oldValueCols = hasFlags(oldValue, DataGridHeadersVisibility.Column);
  577. bool oldValueRows = hasFlags(oldValue, DataGridHeadersVisibility.Row);
  578. // Columns
  579. if (newValueCols != oldValueCols)
  580. {
  581. if (dataGrid._columnHeadersPresenter != null)
  582. {
  583. dataGrid.EnsureColumnHeadersVisibility();
  584. if (!newValueCols)
  585. {
  586. dataGrid._columnHeadersPresenter.Measure(Size.Empty);
  587. }
  588. dataGrid.InvalidateMeasure();
  589. }
  590. }
  591. // Rows
  592. if (newValueRows != oldValueRows)
  593. {
  594. if (dataGrid._rowsPresenter != null)
  595. {
  596. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  597. {
  598. row.EnsureHeaderStyleAndVisibility();
  599. if (newValueRows)
  600. {
  601. row.ApplyState(false /*animate*/);
  602. row.EnsureHeaderVisibility();
  603. }
  604. }
  605. dataGrid.InvalidateRowHeightEstimate();
  606. dataGrid.InvalidateRowsMeasure(true /*invalidateIndividualRows*/);
  607. }
  608. }
  609. //
  610. if (dataGrid._topLeftCornerHeader != null)
  611. {
  612. dataGrid._topLeftCornerHeader.Visibility = newValueRows && newValueCols ? Visibility.Visible : Visibility.Collapsed;
  613. if (dataGrid._topLeftCornerHeader.Visibility == Visibility.Collapsed)
  614. {
  615. dataGrid._topLeftCornerHeader.Measure(Size.Empty);
  616. }
  617. }
  618. }
  619. }
  620. #endregion HeadersVisibility
  621. #region HorizontalGridLinesBrush
  622. /// <summary>
  623. /// Gets or sets a brush that describes the horizontal gridlines color.
  624. /// </summary>
  625. public Brush HorizontalGridLinesBrush
  626. {
  627. get { return GetValue(HorizontalGridLinesBrushProperty) as Brush; }
  628. set { SetValue(HorizontalGridLinesBrushProperty, value); }
  629. }
  630. /// <summary>
  631. /// Identifies the HorizontalGridLinesBrush dependency property.
  632. /// </summary>
  633. public static readonly DependencyProperty HorizontalGridLinesBrushProperty =
  634. DependencyProperty.Register(
  635. "HorizontalGridLinesBrush",
  636. typeof(Brush),
  637. typeof(DataGrid),
  638. new PropertyMetadata(OnHorizontalGridLinesBrushPropertyChanged));
  639. /// <summary>
  640. /// HorizontalGridLinesBrushProperty property changed handler.
  641. /// </summary>
  642. /// <param name="d">DataGrid that changed its HorizontalGridLinesBrush.</param>
  643. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  644. private static void OnHorizontalGridLinesBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  645. {
  646. DataGrid dataGrid = (DataGrid)d;
  647. if (!dataGrid.IsHandlerSuspended(e.Property) && dataGrid._rowsPresenter != null)
  648. {
  649. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  650. {
  651. row.EnsureGridLines();
  652. }
  653. }
  654. }
  655. #endregion HorizontalGridLinesBrush
  656. #region HorizontalScrollBarVisibility
  657. /// <summary>
  658. /// Gets or sets a value that indicates whether a horizontal ScrollBar should be displayed.
  659. /// </summary>
  660. public ScrollBarVisibility HorizontalScrollBarVisibility
  661. {
  662. get { return (ScrollBarVisibility)GetValue(HorizontalScrollBarVisibilityProperty); }
  663. set { SetValue(HorizontalScrollBarVisibilityProperty, value); }
  664. }
  665. /// <summary>
  666. /// Identifies the HorizontalScrollBarVisibility dependency property.
  667. /// </summary>
  668. public static readonly DependencyProperty HorizontalScrollBarVisibilityProperty =
  669. DependencyProperty.Register(
  670. "HorizontalScrollBarVisibility",
  671. typeof(ScrollBarVisibility),
  672. typeof(DataGrid),
  673. new PropertyMetadata(OnHorizontalScrollBarVisibilityPropertyChanged));
  674. /// <summary>
  675. /// HorizontalScrollBarVisibilityProperty property changed handler.
  676. /// </summary>
  677. /// <param name="d">DataGrid that changed its HorizontalScrollBarVisibility.</param>
  678. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  679. private static void OnHorizontalScrollBarVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  680. {
  681. DataGrid dataGrid = (DataGrid)d;
  682. if (!dataGrid.IsHandlerSuspended(e.Property) &&
  683. (ScrollBarVisibility)e.NewValue != (ScrollBarVisibility)e.OldValue &&
  684. dataGrid._hScrollBar != null)
  685. {
  686. dataGrid.InvalidateMeasure();
  687. }
  688. }
  689. #endregion HorizontalScrollBarVisibility
  690. #region IsReadOnly
  691. /// <summary>
  692. /// Gets or sets a value indicating whether the user can edit the cells of the DataGrid control.
  693. /// </summary>
  694. public bool IsReadOnly
  695. {
  696. get { return (bool)GetValue(IsReadOnlyProperty); }
  697. set { SetValue(IsReadOnlyProperty, value); }
  698. }
  699. /// <summary>
  700. /// Identifies the IsReadOnly dependency property.
  701. /// </summary>
  702. public static readonly DependencyProperty IsReadOnlyProperty =
  703. DependencyProperty.Register(
  704. "IsReadOnly",
  705. typeof(bool),
  706. typeof(DataGrid),
  707. new PropertyMetadata(OnIsReadOnlyPropertyChanged));
  708. /// <summary>
  709. /// IsReadOnlyProperty property changed handler.
  710. /// </summary>
  711. /// <param name="d">DataGrid that changed its IsReadOnly.</param>
  712. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  713. private static void OnIsReadOnlyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  714. {
  715. DataGrid dataGrid = (DataGrid)d;
  716. if (!dataGrid.IsHandlerSuspended(e.Property))
  717. {
  718. bool value = (bool)e.NewValue;
  719. if (value && !dataGrid.CommitEdit(DataGridEditingUnit.Row, true /*exitEditing*/))
  720. {
  721. d.SetValueNoCallback(e.Property, e.OldValue);
  722. throw DataGridError.DataGrid.CommitFailedCannotCompleteOperation();
  723. }
  724. }
  725. }
  726. #endregion IsReadOnly
  727. #region ItemsSource
  728. /// <summary>
  729. /// Gets or sets a collection used to generate the content of the DataGrid.
  730. /// </summary>
  731. public IEnumerable ItemsSource
  732. {
  733. get { return GetValue(ItemsSourceProperty) as IEnumerable; }
  734. set { SetValue(ItemsSourceProperty, value); }
  735. }
  736. /// <summary>
  737. /// Identifies the ItemsSource dependency property.
  738. /// </summary>
  739. public static readonly DependencyProperty ItemsSourceProperty =
  740. DependencyProperty.Register(
  741. "ItemsSource",
  742. typeof(IEnumerable),
  743. typeof(DataGrid),
  744. new PropertyMetadata(OnItemsSourcePropertyChanged));
  745. /// <summary>
  746. /// ItemsSourceProperty property changed handler.
  747. /// </summary>
  748. /// <param name="d">DataGrid that changed its ItemsSource.</param>
  749. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  750. private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  751. {
  752. DataGrid dataGrid = (DataGrid)d;
  753. if (!dataGrid.IsHandlerSuspended(e.Property))
  754. {
  755. Debug.Assert(dataGrid.DataConnection != null);
  756. if (dataGrid.LoadingOrUnloadingRow)
  757. {
  758. dataGrid.SetValueNoCallback(ItemsSourceProperty, e.OldValue);
  759. throw DataGridError.DataGrid.CannotChangeItemsWhenLoadingRows();
  760. }
  761. dataGrid.DataConnection.UnWireEvents(dataGrid.DataConnection.DataSource);
  762. dataGrid.DataConnection.ClearDataProperties();
  763. // Wrap an IList in a CollectionView if it's not already one
  764. IEnumerable newDataSource;
  765. IList tempList = e.NewValue as IList;
  766. if (tempList != null && !(e.NewValue is System.ComponentModel.ICollectionView))
  767. {
  768. newDataSource = new ListCollectionView(tempList);
  769. }
  770. else
  771. {
  772. newDataSource = (IEnumerable)e.NewValue;
  773. }
  774. dataGrid.DataConnection.DataSource = newDataSource;
  775. if (newDataSource != null)
  776. {
  777. dataGrid.DataConnection.WireEvents(newDataSource);
  778. }
  779. // we always want to do this
  780. dataGrid.RefreshRowsAndColumns();
  781. }
  782. }
  783. #endregion ItemsSource
  784. #region MaxColumnWidth
  785. /// <summary>
  786. /// Gets or sets the width of the grid's columns.
  787. /// </summary>
  788. public double MaxColumnWidth
  789. {
  790. get { return (double)GetValue(MaxColumnWidthProperty); }
  791. set { SetValue(MaxColumnWidthProperty, value); }
  792. }
  793. /// <summary>
  794. /// Identifies the MaxColumnWidth dependency property.
  795. /// </summary>
  796. public static readonly DependencyProperty MaxColumnWidthProperty =
  797. DependencyProperty.Register(
  798. "MaxColumnWidth",
  799. typeof(double),
  800. typeof(DataGrid),
  801. new PropertyMetadata(OnMaxColumnWidthPropertyChanged));
  802. /// <summary>
  803. /// MaxColumnWidthProperty property changed handler.
  804. /// </summary>
  805. /// <param name="d">DataGrid that changed its ColumnWidth.</param>
  806. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  807. private static void OnMaxColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  808. {
  809. DataGrid dataGrid = (DataGrid)d;
  810. double newValue = (double)e.NewValue;
  811. if (double.IsNaN(newValue))
  812. {
  813. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  814. throw DataGridError.DataGrid.ValueCannotBeSetToNAN("MaxColumnWidth");
  815. }
  816. if (newValue < 0)
  817. {
  818. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  819. throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("value", "MaxColumnWidth", 0);
  820. }
  821. if (dataGrid.MinColumnWidth > newValue)
  822. {
  823. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  824. throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("value", "MaxColumnWidth", "MinColumnWidth");
  825. }
  826. dataGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth();
  827. dataGrid.InvalidateColumnHeadersMeasure();
  828. dataGrid.InvalidateRowsMeasure(true);
  829. }
  830. #endregion MaxColumnWidth
  831. #region MinColumnWidth
  832. /// <summary>
  833. /// Gets or sets the width of the grid's columns.
  834. /// </summary>
  835. public double MinColumnWidth
  836. {
  837. get { return (double)GetValue(MinColumnWidthProperty); }
  838. set { SetValue(MinColumnWidthProperty, value); }
  839. }
  840. /// <summary>
  841. /// Identifies the MinColumnWidth dependency property.
  842. /// </summary>
  843. public static readonly DependencyProperty MinColumnWidthProperty =
  844. DependencyProperty.Register(
  845. "MinColumnWidth",
  846. typeof(double),
  847. typeof(DataGrid),
  848. new PropertyMetadata(OnMinColumnWidthPropertyChanged));
  849. /// <summary>
  850. /// MinColumnWidthProperty property changed handler.
  851. /// </summary>
  852. /// <param name="d">DataGrid that changed its ColumnWidth.</param>
  853. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  854. private static void OnMinColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  855. {
  856. DataGrid dataGrid = (DataGrid)d;
  857. double newValue = (double)e.NewValue;
  858. if (double.IsNaN(newValue))
  859. {
  860. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  861. throw DataGridError.DataGrid.ValueCannotBeSetToNAN("MinColumnWidth");
  862. }
  863. if (newValue < 0)
  864. {
  865. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  866. throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("value", "MinColumnWidth", 0);
  867. }
  868. if (double.IsPositiveInfinity(newValue))
  869. {
  870. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  871. throw DataGridError.DataGrid.ValueCannotBeSetToInfinity("MinColumnWidth");
  872. }
  873. if (dataGrid.MaxColumnWidth < newValue)
  874. {
  875. dataGrid.SetValueNoCallback(e.Property, e.OldValue);
  876. throw DataGridError.DataGrid.ValueMustBeLessThanOrEqualTo("value", "MinColumnWidth", "MaxColumnWidth");
  877. }
  878. dataGrid.ColumnsInternal.EnsureVisibleEdgedColumnsWidth();
  879. dataGrid.InvalidateColumnHeadersMeasure();
  880. dataGrid.InvalidateRowsMeasure(true);
  881. }
  882. #endregion MinColumnWidth
  883. #region RowBackground
  884. /// <summary>
  885. /// Gets or sets a brush that describes the background of a row in the grid.
  886. /// </summary>
  887. public Brush RowBackground
  888. {
  889. get { return GetValue(RowBackgroundProperty) as Brush; }
  890. set { SetValue(RowBackgroundProperty, value); }
  891. }
  892. public static readonly DependencyProperty RowBackgroundProperty = DependencyProperty.Register("RowBackground", typeof(Brush), typeof(DataGrid), new PropertyMetadata(OnRowBackgroundPropertyChanged));
  893. private static void OnRowBackgroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  894. {
  895. DataGrid dataGrid = (DataGrid)d;
  896. if (dataGrid._rowsPresenter != null)
  897. {
  898. // Go through the Displayed rows and update the background
  899. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  900. {
  901. row.EnsureBackground();
  902. }
  903. }
  904. }
  905. #endregion RowBackground
  906. #region RowDetailsTemplate
  907. /// <summary>
  908. /// Gets or sets the DataTemplate used to display the details section of a row.
  909. /// </summary>
  910. public DataTemplate RowDetailsTemplate
  911. {
  912. get { return GetValue(RowDetailsTemplateProperty) as DataTemplate; }
  913. set { SetValue(RowDetailsTemplateProperty, value); }
  914. }
  915. /// <summary>
  916. /// Identifies the RowDetailsTemplate dependency property.
  917. /// </summary>
  918. public static readonly DependencyProperty RowDetailsTemplateProperty =
  919. DependencyProperty.Register(
  920. "RowDetailsTemplate",
  921. typeof(DataTemplate),
  922. typeof(DataGrid),
  923. new PropertyMetadata(OnRowDetailsTemplatePropertyChanged));
  924. private static void OnRowDetailsTemplatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  925. {
  926. DataGrid dataGrid = (DataGrid)d;
  927. // Update the RowDetails templates if necessary
  928. if (dataGrid._rowsPresenter != null)
  929. {
  930. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  931. {
  932. if (dataGrid.GetRowDetailsVisibility(row.Index) == Visibility.Visible)
  933. {
  934. // DetailsPreferredHeight is initialized when the DetailsElement's size changes.
  935. row.ApplyDetailsTemplate(false /*initializeDetailsPreferredHeight*/);
  936. }
  937. }
  938. }
  939. dataGrid.UpdateRowDetailsHeightEstimate();
  940. dataGrid.InvalidateMeasure();
  941. }
  942. #endregion RowDetailsTemplate
  943. #region RowDetailsVisibilityMode
  944. /// <summary>
  945. /// Gets or sets a value that indicates when the details section of a row should be displayed.
  946. /// </summary>
  947. //
  948. [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
  949. public DataGridRowDetailsVisibilityMode RowDetailsVisibilityMode
  950. {
  951. get { return (DataGridRowDetailsVisibilityMode)GetValue(RowDetailsVisibilityModeProperty); }
  952. set { SetValue(RowDetailsVisibilityModeProperty, value); }
  953. }
  954. /// <summary>
  955. /// Identifies the RowDetailsVisibilityMode dependency property.
  956. /// </summary>
  957. public static readonly DependencyProperty RowDetailsVisibilityModeProperty =
  958. DependencyProperty.Register(
  959. "RowDetailsVisibilityMode",
  960. typeof(DataGridRowDetailsVisibilityMode),
  961. typeof(DataGrid),
  962. new PropertyMetadata(OnRowDetailsVisibilityModePropertyChanged));
  963. /// <summary>
  964. /// RowDetailsVisibilityModeProperty property changed handler.
  965. /// </summary>
  966. /// <param name="d">DataGrid that changed its RowDetailsVisibilityMode.</param>
  967. /// <param name="e">DependencyPropertyChangedEventArgs.</param>
  968. private static void OnRowDetailsVisibilityModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  969. {
  970. DataGrid dataGrid = (DataGrid)d;
  971. if (dataGrid._rowsPresenter != null && dataGrid.RowCount > 0)
  972. {
  973. DataGridRowDetailsVisibilityMode newDetailsMode = (DataGridRowDetailsVisibilityMode)e.NewValue;
  974. Visibility newDetailsVisibility = Visibility.Collapsed;
  975. switch (newDetailsMode)
  976. {
  977. case DataGridRowDetailsVisibilityMode.Visible:
  978. newDetailsVisibility = Visibility.Visible;
  979. dataGrid._showDetailsTable.AddValues(0, dataGrid.RowCount, Visibility.Visible);
  980. break;
  981. case DataGridRowDetailsVisibilityMode.Collapsed:
  982. newDetailsVisibility = Visibility.Collapsed;
  983. dataGrid._showDetailsTable.AddValues(0, dataGrid.RowCount, Visibility.Collapsed);
  984. break;
  985. case DataGridRowDetailsVisibilityMode.VisibleWhenSelected:
  986. dataGrid._showDetailsTable.Clear();
  987. break;
  988. }
  989. bool updated = false;
  990. foreach (DataGridRow row in dataGrid._rowsPresenter.Children)
  991. {
  992. Debug.Assert(row.Index != -1);
  993. if (newDetailsMode == DataGridRowDetailsVisibilityMode.VisibleWhenSelected)
  994. {
  995. // For VisibleWhenSelected, we need to calculate the value for each individual row
  996. newDetailsVisibility = dataGrid._selectedItems.Contains(row.Index) ? Visibility.Visible : Visibility.Collapsed;
  997. }
  998. if (row.DetailsVisibility != newDetailsVisibility)
  999. {
  1000. updated = true;
  1001. row.SetDetailsVisibilityInternal(newDetailsVisibility, true /* raiseNotification */, false /* animate */);
  1002. }
  1003. }
  1004. if (updated)
  1005. {
  1006. dataGrid.UpdateDisplayedRows(dataGrid.DisplayData.FirstDisplayedScrollingRow, dataGrid.CellsHeight);
  1007. dataGrid.InvalidateRowsMeasure(false /*invalidateIndividualRows*/);

Large files files are truncated, but you can click here to view the full file