Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ControlUtil.cs
- FormViewModeEventArgs.cs
- ProcessHostServerConfig.cs
- ViewUtilities.cs
- PreservationFileWriter.cs
- ChannelManager.cs
- AlternateViewCollection.cs
- WebServiceParameterData.cs
- SpinWait.cs
- TextServicesManager.cs
- ClrPerspective.cs
- messageonlyhwndwrapper.cs
- VectorCollectionValueSerializer.cs
- IInstanceContextProvider.cs
- Int16AnimationBase.cs
- ConnectionProviderAttribute.cs
- BehaviorEditorPart.cs
- Emitter.cs
- MissingFieldException.cs
- CodeTypeDeclarationCollection.cs
- XmlBaseWriter.cs
- DesignerVerbCollection.cs
- DesignerAttributeInfo.cs
- Scene3D.cs
- PackagePart.cs
- GeneralTransform3DTo2DTo3D.cs
- SchemaImporterExtensionElement.cs
- ControlIdConverter.cs
- UpdateCommandGenerator.cs
- ListBoxItem.cs
- FactoryGenerator.cs
- KeySplineConverter.cs
- MessageSmuggler.cs
- VirtualDirectoryMappingCollection.cs
- SocketAddress.cs
- MinimizableAttributeTypeConverter.cs
- WindowsSolidBrush.cs
- IdentitySection.cs
- PenThread.cs
- TypedCompletedAsyncResult.cs
- BigInt.cs
- FixedStringLookup.cs
- TableSectionStyle.cs
- HtmlInputSubmit.cs
- ObjectConverter.cs
- SpecularMaterial.cs
- EdmRelationshipNavigationPropertyAttribute.cs
- TreeBuilder.cs
- TemplateBamlTreeBuilder.cs
- DataServiceHostFactory.cs
- AssociationTypeEmitter.cs
- CodePropertyReferenceExpression.cs
- SvcMapFileLoader.cs
- ClientData.cs
- ExpandoClass.cs
- X509UI.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- JournalEntry.cs
- CodeMemberEvent.cs
- FolderBrowserDialog.cs
- SspiWrapper.cs
- DispatcherObject.cs
- UnknownBitmapDecoder.cs
- CallContext.cs
- TabControlEvent.cs
- WebBrowserSiteBase.cs
- FontUnitConverter.cs
- ForceCopyBuildProvider.cs
- KeysConverter.cs
- SoapSchemaExporter.cs
- InputGestureCollection.cs
- DefaultHttpHandler.cs
- DrawingContextDrawingContextWalker.cs
- TextCollapsingProperties.cs
- AnnotationStore.cs
- GridProviderWrapper.cs
- PersistenceTypeAttribute.cs
- DelegateBodyWriter.cs
- CompoundFileDeflateTransform.cs
- DataGridBoolColumn.cs
- AddInAttribute.cs
- StringAttributeCollection.cs
- SecurityException.cs
- SecureStringHasher.cs
- DoubleLink.cs
- ActivityMarkupSerializationProvider.cs
- SqlHelper.cs
- HandlerFactoryWrapper.cs
- PeerNameRegistration.cs
- ServiceBehaviorElementCollection.cs
- Reference.cs
- PngBitmapEncoder.cs
- StreamMarshaler.cs
- TextEditorTables.cs
- XmlSerializationGeneratedCode.cs
- ComboBox.cs
- UpdateException.cs
- SHA256.cs
- _ListenerRequestStream.cs
- VirtualizedItemProviderWrapper.cs