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
- Funcletizer.cs
- Image.cs
- GenericEnumerator.cs
- UnsafeCollabNativeMethods.cs
- ManagementInstaller.cs
- XsltInput.cs
- IArgumentProvider.cs
- Visual3D.cs
- EmptyWithCancelationCheckWorkItem.cs
- StylusPlugin.cs
- Listbox.cs
- NamespaceQuery.cs
- TimelineGroup.cs
- ForwardPositionQuery.cs
- ArraySortHelper.cs
- base64Transforms.cs
- LinkClickEvent.cs
- SqlTypesSchemaImporter.cs
- DatagridviewDisplayedBandsData.cs
- PathFigure.cs
- NavigationHelper.cs
- SQLBoolean.cs
- CustomLineCap.cs
- ProviderSettings.cs
- PartialCachingControl.cs
- PropertyToken.cs
- TextElementCollection.cs
- DirectoryLocalQuery.cs
- RadioButtonFlatAdapter.cs
- HTMLTagNameToTypeMapper.cs
- MergeLocalizationDirectives.cs
- WindowsTitleBar.cs
- SchemaContext.cs
- XmlDataSourceNodeDescriptor.cs
- BoundConstants.cs
- ExpressionBuilderCollection.cs
- ExternalException.cs
- GeometryDrawing.cs
- OletxCommittableTransaction.cs
- DiffuseMaterial.cs
- ChtmlMobileTextWriter.cs
- SimpleWorkerRequest.cs
- X509CertificateTrustedIssuerElementCollection.cs
- XmlDocumentType.cs
- FileDialogPermission.cs
- ArgumentOutOfRangeException.cs
- HandlerBase.cs
- Pkcs7Recipient.cs
- DynamicDataRouteHandler.cs
- InplaceBitmapMetadataWriter.cs
- GlobalizationSection.cs
- CellConstant.cs
- HttpModulesSection.cs
- XmlReaderSettings.cs
- OdbcDataAdapter.cs
- MobileUserControl.cs
- PerformanceCounterPermissionAttribute.cs
- SystemMulticastIPAddressInformation.cs
- StatusInfoItem.cs
- SerializerDescriptor.cs
- safex509handles.cs
- FatalException.cs
- ScopelessEnumAttribute.cs
- RtfToXamlReader.cs
- GetPolicyDetailsRequest.cs
- CallbackHandler.cs
- clipboard.cs
- AttachmentCollection.cs
- DesignerActionMethodItem.cs
- RealProxy.cs
- Row.cs
- DataTableReaderListener.cs
- StyleSheetDesigner.cs
- WindowsListViewGroupSubsetLink.cs
- AppLevelCompilationSectionCache.cs
- ReferenceCountedObject.cs
- MissingMemberException.cs
- ColumnReorderedEventArgs.cs
- AssemblyNameUtility.cs
- odbcmetadatacollectionnames.cs
- HtmlAnchor.cs
- NamedPermissionSet.cs
- CroppedBitmap.cs
- PermissionSetEnumerator.cs
- EncryptedKeyIdentifierClause.cs
- ListViewTableCell.cs
- EntityDataSourceDataSelectionPanel.cs
- TextCompositionManager.cs
- SaveFileDialog.cs
- DataGridViewAdvancedBorderStyle.cs
- remotingproxy.cs
- BindingMemberInfo.cs
- ProtocolElementCollection.cs
- ThicknessConverter.cs
- MaskDesignerDialog.cs
- TraceUtils.cs
- ConstructorExpr.cs
- DeflateEmulationStream.cs
- WindowsGraphicsWrapper.cs
- HashCodeCombiner.cs