Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Primitives / DataGridDetailsPresenter.cs / 1305600 / DataGridDetailsPresenter.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace System.Windows.Controls.Primitives { public class DataGridDetailsPresenter : ContentPresenter { static DataGridDetailsPresenter() { DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridDetailsPresenter), new FrameworkPropertyMetadata(typeof(DataGridDetailsPresenter))); ContentTemplateProperty.OverrideMetadata(typeof(DataGridDetailsPresenter), new FrameworkPropertyMetadata(OnNotifyPropertyChanged, OnCoerceContentTemplate)); ContentTemplateSelectorProperty.OverrideMetadata(typeof(DataGridDetailsPresenter), new FrameworkPropertyMetadata(OnNotifyPropertyChanged, OnCoerceContentTemplateSelector)); EventManager.RegisterClassHandler(typeof(DataGridDetailsPresenter), MouseLeftButtonDownEvent, new MouseButtonEventHandler(OnAnyMouseLeftButtonDownThunk), true); } ////// Instantiates a new instance of this class. /// public DataGridDetailsPresenter() { } #region Automation protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer() { return new System.Windows.Automation.Peers.DataGridDetailsPresenterAutomationPeer(this); } #endregion #region Coercion ////// Coerces the ContentTemplate property. /// private static object OnCoerceContentTemplate(DependencyObject d, object baseValue) { var details = d as DataGridDetailsPresenter; var row = details.DataGridRowOwner; var dataGrid = row != null ? row.DataGridOwner : null; return DataGridHelper.GetCoercedTransferPropertyValue( details, baseValue, ContentTemplateProperty, row, DataGridRow.DetailsTemplateProperty, dataGrid, DataGrid.RowDetailsTemplateProperty); } ////// Coerces the ContentTemplateSelector property. /// private static object OnCoerceContentTemplateSelector(DependencyObject d, object baseValue) { var details = d as DataGridDetailsPresenter; var row = details.DataGridRowOwner; var dataGrid = row != null ? row.DataGridOwner : null; return DataGridHelper.GetCoercedTransferPropertyValue( details, baseValue, ContentTemplateSelectorProperty, row, DataGridRow.DetailsTemplateSelectorProperty, dataGrid, DataGrid.RowDetailsTemplateSelectorProperty); } #endregion #region Row Communication protected internal override void OnVisualParentChanged(DependencyObject oldParent) { base.OnVisualParentChanged(oldParent); // DataGridRow.DetailsPresenter is used by automation peers // Give the Row a pointer to the RowHeader so that it can propagate down change notifications DataGridRow owner = DataGridRowOwner; if (owner != null) { owner.DetailsPresenter = this; // At the time that a Row is prepared we can't [....] because the DetailsPresenter isn't created yet. // Doing it here ensures that the DetailsPresenter is in the visual tree. SyncProperties(); } } private static void OnAnyMouseLeftButtonDownThunk(object sender, MouseButtonEventArgs e) { ((DataGridDetailsPresenter)sender).OnAnyMouseLeftButtonDown(e); } private void OnAnyMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) { // Ignore actions if the button down arises from a different presentation source if (!PresentationSource.UnderSamePresentationSource(e.OriginalSource as DependencyObject, this)) { return; } DataGridRow rowOwner = DataGridRowOwner; DataGrid dataGridOwner = rowOwner != null ? rowOwner.DataGridOwner : null; if ((dataGridOwner != null) && (rowOwner != null)) { // HandleSelectionForRowHeaderAndDetailsInput below sets the CurrentCell // of datagrid to the cell with displayindex 0 in the row. // This implicitly queues a request to MakeVisible command // of ScrollViewer. The command handler calls MakeVisible method of // VirtualizingStackPanel (of rows presenter) which works only // when the visual's parent layout is clean. DataGridCellsPanel layout is // not clean as per MakeVisible of VSP becuase we distribute the layout of cells for the // sake of row headers and hence it fails. VSP.MakeVisible method requeues a request to // ScrollViewer.MakeVisible command hence resulting into an infinite loop. // The workaround is to bring the concerned cell into the view by calling // ScrollIntoView so that by the time MakeVisible handler of ScrollViewer is // executed the cell is already visible and the handler succeeds. if (dataGridOwner.CurrentCell.Item != rowOwner.Item) { dataGridOwner.ScrollIntoView(rowOwner.Item, dataGridOwner.ColumnFromDisplayIndex(0)); } dataGridOwner.HandleSelectionForRowHeaderAndDetailsInput(rowOwner, /* startDragging = */ Mouse.Captured == null); } } internal FrameworkElement DetailsElement { get { var childrenCount = VisualTreeHelper.GetChildrenCount(this); if (childrenCount > 0) { return VisualTreeHelper.GetChild(this, 0) as FrameworkElement; } return null; } } ////// Update all properties that get a value from the DataGrid /// ////// See comment on DataGridRow.OnDataGridChanged /// internal void SyncProperties() { DataGridRow owner = DataGridRowOwner; Content = owner != null ? owner.Item : null; DataGridHelper.TransferProperty(this, ContentTemplateProperty); DataGridHelper.TransferProperty(this, ContentTemplateSelectorProperty); } #endregion #region Notification Propagation ////// Notifies parts that respond to changes in the properties. /// private static void OnNotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((DataGridDetailsPresenter)d).NotifyPropertyChanged(d, e); } internal void NotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.Property == DataGrid.RowDetailsTemplateProperty || e.Property == DataGridRow.DetailsTemplateProperty || e.Property == ContentTemplateProperty) { DataGridHelper.TransferProperty(this, ContentTemplateProperty); } else if (e.Property == DataGrid.RowDetailsTemplateSelectorProperty || e.Property == DataGridRow.DetailsTemplateSelectorProperty || e.Property == ContentTemplateSelectorProperty) { DataGridHelper.TransferProperty(this, ContentTemplateSelectorProperty); } } #endregion #region GridLines // Different parts of the DataGrid draw different pieces of the GridLines. // Rows draw a single horizontal line on the bottom. The DataGridDetailsPresenter is the element that handles it. ////// Measure. This is overridden so that the row can extend its size to account for a grid line on the bottom. /// /// ///protected override Size MeasureOverride(Size availableSize) { // Make space for the GridLine on the bottom. // Remove space from the constraint (since it implicitly includes the GridLine's thickness), // call the base implementation, and add the thickness back for the returned size. var row = DataGridRowOwner; if (row == null) { return base.MeasureOverride(availableSize); } var dataGrid = row.DataGridOwner; if (dataGrid == null) { return base.MeasureOverride(availableSize); } if (row.DetailsPresenterDrawsGridLines && DataGridHelper.IsGridLineVisible(dataGrid, /*isHorizontal = */ true)) { double thickness = dataGrid.HorizontalGridLineThickness; Size desiredSize = base.MeasureOverride(DataGridHelper.SubtractFromSize(availableSize, thickness, /*height = */ true)); desiredSize.Height += thickness; return desiredSize; } else { return base.MeasureOverride(availableSize); } } /// /// Arrange. This is overriden so that the row can position its content to account for a grid line on the bottom. /// /// Arrange size protected override Size ArrangeOverride(Size finalSize) { // We don't need to adjust the Arrange position of the content. By default it is arranged at 0,0 and we're // adding a line to the bottom. All we have to do is compress and extend the size, just like Measure. var row = DataGridRowOwner; if (row == null) { return base.ArrangeOverride(finalSize); } var dataGrid = row.DataGridOwner; if (dataGrid == null) { return base.ArrangeOverride(finalSize); } if (row.DetailsPresenterDrawsGridLines && DataGridHelper.IsGridLineVisible(dataGrid, /*isHorizontal = */ true)) { double thickness = dataGrid.HorizontalGridLineThickness; Size returnSize = base.ArrangeOverride(DataGridHelper.SubtractFromSize(finalSize, thickness, /*height = */ true)); returnSize.Height += thickness; return returnSize; } else { return base.ArrangeOverride(finalSize); } } ////// OnRender. Overriden to draw a horizontal line underneath the content. /// /// protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); var row = DataGridRowOwner; if (row == null) { return; } var dataGrid = row.DataGridOwner; if (dataGrid == null) { return; } if (row.DetailsPresenterDrawsGridLines && DataGridHelper.IsGridLineVisible(dataGrid, /*isHorizontal = */ true)) { double thickness = dataGrid.HorizontalGridLineThickness; Rect rect = new Rect(new Size(RenderSize.Width, thickness)); rect.Y = RenderSize.Height - thickness; drawingContext.DrawRectangle(dataGrid.HorizontalGridLinesBrush, null, rect); } } #endregion #region Helpers ////// The DataGrid that owns this control /// private DataGrid DataGridOwner { get { DataGridRow owner = DataGridRowOwner; if (owner != null) { return owner.DataGridOwner; } return null; } } ////// The DataGridRow that owns this control. /// internal DataGridRow DataGridRowOwner { get { return DataGridHelper.FindParent(this); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace System.Windows.Controls.Primitives { public class DataGridDetailsPresenter : ContentPresenter { static DataGridDetailsPresenter() { DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridDetailsPresenter), new FrameworkPropertyMetadata(typeof(DataGridDetailsPresenter))); ContentTemplateProperty.OverrideMetadata(typeof(DataGridDetailsPresenter), new FrameworkPropertyMetadata(OnNotifyPropertyChanged, OnCoerceContentTemplate)); ContentTemplateSelectorProperty.OverrideMetadata(typeof(DataGridDetailsPresenter), new FrameworkPropertyMetadata(OnNotifyPropertyChanged, OnCoerceContentTemplateSelector)); EventManager.RegisterClassHandler(typeof(DataGridDetailsPresenter), MouseLeftButtonDownEvent, new MouseButtonEventHandler(OnAnyMouseLeftButtonDownThunk), true); } /// /// Instantiates a new instance of this class. /// public DataGridDetailsPresenter() { } #region Automation protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer() { return new System.Windows.Automation.Peers.DataGridDetailsPresenterAutomationPeer(this); } #endregion #region Coercion ////// Coerces the ContentTemplate property. /// private static object OnCoerceContentTemplate(DependencyObject d, object baseValue) { var details = d as DataGridDetailsPresenter; var row = details.DataGridRowOwner; var dataGrid = row != null ? row.DataGridOwner : null; return DataGridHelper.GetCoercedTransferPropertyValue( details, baseValue, ContentTemplateProperty, row, DataGridRow.DetailsTemplateProperty, dataGrid, DataGrid.RowDetailsTemplateProperty); } ////// Coerces the ContentTemplateSelector property. /// private static object OnCoerceContentTemplateSelector(DependencyObject d, object baseValue) { var details = d as DataGridDetailsPresenter; var row = details.DataGridRowOwner; var dataGrid = row != null ? row.DataGridOwner : null; return DataGridHelper.GetCoercedTransferPropertyValue( details, baseValue, ContentTemplateSelectorProperty, row, DataGridRow.DetailsTemplateSelectorProperty, dataGrid, DataGrid.RowDetailsTemplateSelectorProperty); } #endregion #region Row Communication protected internal override void OnVisualParentChanged(DependencyObject oldParent) { base.OnVisualParentChanged(oldParent); // DataGridRow.DetailsPresenter is used by automation peers // Give the Row a pointer to the RowHeader so that it can propagate down change notifications DataGridRow owner = DataGridRowOwner; if (owner != null) { owner.DetailsPresenter = this; // At the time that a Row is prepared we can't [....] because the DetailsPresenter isn't created yet. // Doing it here ensures that the DetailsPresenter is in the visual tree. SyncProperties(); } } private static void OnAnyMouseLeftButtonDownThunk(object sender, MouseButtonEventArgs e) { ((DataGridDetailsPresenter)sender).OnAnyMouseLeftButtonDown(e); } private void OnAnyMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) { // Ignore actions if the button down arises from a different presentation source if (!PresentationSource.UnderSamePresentationSource(e.OriginalSource as DependencyObject, this)) { return; } DataGridRow rowOwner = DataGridRowOwner; DataGrid dataGridOwner = rowOwner != null ? rowOwner.DataGridOwner : null; if ((dataGridOwner != null) && (rowOwner != null)) { // HandleSelectionForRowHeaderAndDetailsInput below sets the CurrentCell // of datagrid to the cell with displayindex 0 in the row. // This implicitly queues a request to MakeVisible command // of ScrollViewer. The command handler calls MakeVisible method of // VirtualizingStackPanel (of rows presenter) which works only // when the visual's parent layout is clean. DataGridCellsPanel layout is // not clean as per MakeVisible of VSP becuase we distribute the layout of cells for the // sake of row headers and hence it fails. VSP.MakeVisible method requeues a request to // ScrollViewer.MakeVisible command hence resulting into an infinite loop. // The workaround is to bring the concerned cell into the view by calling // ScrollIntoView so that by the time MakeVisible handler of ScrollViewer is // executed the cell is already visible and the handler succeeds. if (dataGridOwner.CurrentCell.Item != rowOwner.Item) { dataGridOwner.ScrollIntoView(rowOwner.Item, dataGridOwner.ColumnFromDisplayIndex(0)); } dataGridOwner.HandleSelectionForRowHeaderAndDetailsInput(rowOwner, /* startDragging = */ Mouse.Captured == null); } } internal FrameworkElement DetailsElement { get { var childrenCount = VisualTreeHelper.GetChildrenCount(this); if (childrenCount > 0) { return VisualTreeHelper.GetChild(this, 0) as FrameworkElement; } return null; } } ////// Update all properties that get a value from the DataGrid /// ////// See comment on DataGridRow.OnDataGridChanged /// internal void SyncProperties() { DataGridRow owner = DataGridRowOwner; Content = owner != null ? owner.Item : null; DataGridHelper.TransferProperty(this, ContentTemplateProperty); DataGridHelper.TransferProperty(this, ContentTemplateSelectorProperty); } #endregion #region Notification Propagation ////// Notifies parts that respond to changes in the properties. /// private static void OnNotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((DataGridDetailsPresenter)d).NotifyPropertyChanged(d, e); } internal void NotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.Property == DataGrid.RowDetailsTemplateProperty || e.Property == DataGridRow.DetailsTemplateProperty || e.Property == ContentTemplateProperty) { DataGridHelper.TransferProperty(this, ContentTemplateProperty); } else if (e.Property == DataGrid.RowDetailsTemplateSelectorProperty || e.Property == DataGridRow.DetailsTemplateSelectorProperty || e.Property == ContentTemplateSelectorProperty) { DataGridHelper.TransferProperty(this, ContentTemplateSelectorProperty); } } #endregion #region GridLines // Different parts of the DataGrid draw different pieces of the GridLines. // Rows draw a single horizontal line on the bottom. The DataGridDetailsPresenter is the element that handles it. ////// Measure. This is overridden so that the row can extend its size to account for a grid line on the bottom. /// /// ///protected override Size MeasureOverride(Size availableSize) { // Make space for the GridLine on the bottom. // Remove space from the constraint (since it implicitly includes the GridLine's thickness), // call the base implementation, and add the thickness back for the returned size. var row = DataGridRowOwner; if (row == null) { return base.MeasureOverride(availableSize); } var dataGrid = row.DataGridOwner; if (dataGrid == null) { return base.MeasureOverride(availableSize); } if (row.DetailsPresenterDrawsGridLines && DataGridHelper.IsGridLineVisible(dataGrid, /*isHorizontal = */ true)) { double thickness = dataGrid.HorizontalGridLineThickness; Size desiredSize = base.MeasureOverride(DataGridHelper.SubtractFromSize(availableSize, thickness, /*height = */ true)); desiredSize.Height += thickness; return desiredSize; } else { return base.MeasureOverride(availableSize); } } /// /// Arrange. This is overriden so that the row can position its content to account for a grid line on the bottom. /// /// Arrange size protected override Size ArrangeOverride(Size finalSize) { // We don't need to adjust the Arrange position of the content. By default it is arranged at 0,0 and we're // adding a line to the bottom. All we have to do is compress and extend the size, just like Measure. var row = DataGridRowOwner; if (row == null) { return base.ArrangeOverride(finalSize); } var dataGrid = row.DataGridOwner; if (dataGrid == null) { return base.ArrangeOverride(finalSize); } if (row.DetailsPresenterDrawsGridLines && DataGridHelper.IsGridLineVisible(dataGrid, /*isHorizontal = */ true)) { double thickness = dataGrid.HorizontalGridLineThickness; Size returnSize = base.ArrangeOverride(DataGridHelper.SubtractFromSize(finalSize, thickness, /*height = */ true)); returnSize.Height += thickness; return returnSize; } else { return base.ArrangeOverride(finalSize); } } ////// OnRender. Overriden to draw a horizontal line underneath the content. /// /// protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); var row = DataGridRowOwner; if (row == null) { return; } var dataGrid = row.DataGridOwner; if (dataGrid == null) { return; } if (row.DetailsPresenterDrawsGridLines && DataGridHelper.IsGridLineVisible(dataGrid, /*isHorizontal = */ true)) { double thickness = dataGrid.HorizontalGridLineThickness; Rect rect = new Rect(new Size(RenderSize.Width, thickness)); rect.Y = RenderSize.Height - thickness; drawingContext.DrawRectangle(dataGrid.HorizontalGridLinesBrush, null, rect); } } #endregion #region Helpers ////// The DataGrid that owns this control /// private DataGrid DataGridOwner { get { DataGridRow owner = DataGridRowOwner; if (owner != null) { return owner.DataGridOwner; } return null; } } ////// The DataGridRow that owns this control. /// internal DataGridRow DataGridRowOwner { get { return DataGridHelper.FindParent(this); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BitmapEffectDrawing.cs
- sqlnorm.cs
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- DocumentSequence.cs
- LambdaExpression.cs
- TrustLevel.cs
- DataGridViewCellCancelEventArgs.cs
- ObjectQuery_EntitySqlExtensions.cs
- TripleDES.cs
- NameValuePair.cs
- COM2AboutBoxPropertyDescriptor.cs
- MessagePropertyFilter.cs
- _KerberosClient.cs
- PeerPresenceInfo.cs
- _SSPIWrapper.cs
- Int32KeyFrameCollection.cs
- SymLanguageType.cs
- Size3DConverter.cs
- DataViewListener.cs
- WebPartEditVerb.cs
- ItemsControlAutomationPeer.cs
- HandlerBase.cs
- ModelTreeEnumerator.cs
- MenuCommand.cs
- WebPartDescription.cs
- CancellationTokenRegistration.cs
- ILGenerator.cs
- CodeDefaultValueExpression.cs
- ColumnClickEvent.cs
- ObjectToken.cs
- NetMsmqSecurity.cs
- DrawingBrush.cs
- ProgressiveCrcCalculatingStream.cs
- ButtonBase.cs
- CodeGen.cs
- Symbol.cs
- DataGridComboBoxColumn.cs
- QueryAccessibilityHelpEvent.cs
- MappedMetaModel.cs
- ComponentChangingEvent.cs
- UdpAnnouncementEndpoint.cs
- FileDetails.cs
- TextTreeExtractElementUndoUnit.cs
- WebPartUtil.cs
- OutOfMemoryException.cs
- QuotedPrintableStream.cs
- Timeline.cs
- WindowsTokenRoleProvider.cs
- ColumnHeaderConverter.cs
- ExpressionVisitor.cs
- HttpCookieCollection.cs
- XmlSchemaInferenceException.cs
- CustomWebEventKey.cs
- ReadOnlyDictionary.cs
- BlurBitmapEffect.cs
- SourceSwitch.cs
- SymDocumentType.cs
- SequentialWorkflowRootDesigner.cs
- FrameworkContextData.cs
- FrameworkReadOnlyPropertyMetadata.cs
- JulianCalendar.cs
- XmlSchema.cs
- Control.cs
- WrapperEqualityComparer.cs
- SqlDataSourceView.cs
- MultiDataTrigger.cs
- MouseGestureValueSerializer.cs
- DiagnosticTrace.cs
- FtpWebResponse.cs
- FixUp.cs
- CopyOfAction.cs
- XmlEntity.cs
- KeyValuePairs.cs
- COAUTHIDENTITY.cs
- Brushes.cs
- PropertyChangingEventArgs.cs
- ConfigurationProperty.cs
- TextContainerHelper.cs
- CAGDesigner.cs
- ScrollItemPattern.cs
- ReadWriteSpinLock.cs
- SizeValueSerializer.cs
- SchemaImporterExtensionElement.cs
- ButtonBaseAdapter.cs
- PropertyEmitter.cs
- SQLInt16.cs
- MetabaseServerConfig.cs
- ObjectHandle.cs
- DynamicDataResources.Designer.cs
- WindowsFormsHost.cs
- TraceContext.cs
- ContainerAction.cs
- BooleanProjectedSlot.cs
- RectangleGeometry.cs
- MsmqReceiveParameters.cs
- EditingCoordinator.cs
- SqlCacheDependencyDatabaseCollection.cs
- WriteStateInfoBase.cs
- StringFormat.cs
- ManipulationLogic.cs