/// <summary> /// Creates a GUI column from the given properties. /// </summary> /// <param name="pColumn">The column properties.</param> /// <param name="pIndex">The column index.</param> /// <returns>The created column.</returns> public static ExtendedGridViewColumn CreateFrom(TreeListViewColumn pColumn, int pIndex) { ExtendedGridViewColumn lColumn = new ExtendedGridViewColumn(); // Header. lColumn.Header = pColumn.Header; // Width. GridLength lWidth = new GridLength(); if (pColumn.Stretch) { lWidth = new GridLength(pColumn.Width, GridUnitType.Star); } else { lWidth = new GridLength(pColumn.Width, GridUnitType.Pixel); } lColumn.GridLength = lWidth; // Template selector. if (pColumn.TemplateSelector != null) { lColumn.CellTemplateSelector = pColumn.TemplateSelector; } else { // Template. lColumn.CellTemplate = XTreeListView.Resources.All.Instance.GetCellTemplate(pColumn.DisplayMemberPath); } return(lColumn); }
/// <summary> /// Updates the grid view columns with the given collection. /// </summary> /// <param name="pCollection">The collection to synchronize.</param> internal void SynchronizeColumns(TreeListViewColumnCollection pCollection) { // Clearing columns. this.Columns.Clear(); for (int lIter = 0; lIter < pCollection.Count; lIter++) { // Creating a column for each backuped column. ExtendedGridViewColumn lColumn = ExtendedGridViewColumn.CreateFrom(pCollection[lIter], lIter); // Indenting the data template used in the first column. if (lIter == 0) { // Extra margin between the end of the decorators part and the beginning of the item data template to remove. double lExtraMargin = 4; // Creating the indentation of the data template. Binding lTemplateMarginBinding = new Binding("DecoratorWidth"); lTemplateMarginBinding.Converter = new WidthToLeftMarginConverter() { Margin = lExtraMargin }; // Creating the new cell data template. System.Windows.DataTemplate lCellDataTemplate = new System.Windows.DataTemplate(); // Defining the visual tree. FrameworkElementFactory lCellFactory = new FrameworkElementFactory(typeof(ContentControl)); lCellFactory.SetBinding(ContentControl.MarginProperty, lTemplateMarginBinding); lCellFactory.SetBinding(ContentControl.ContentProperty, new Binding() { BindsDirectlyToSource = true }); // Trying to get the data template already defined in the first column. if (lColumn.CellTemplate != null) { lCellFactory.SetValue(ContentControl.ContentTemplateProperty, lColumn.CellTemplate); // Removing the template from the cell as it is now applied in the ContentControl. lColumn.CellTemplate = null; } // Trying to get the data template selector if any. if (lColumn.CellTemplateSelector != null) { lCellFactory.SetValue(ContentControl.ContentTemplateSelectorProperty, lColumn.CellTemplateSelector); // Removing the template selector from the cell as it is now applied in the ContentControl. lColumn.CellTemplateSelector = null; } // Trying to get the display path. if (lColumn.DisplayMemberBinding != null) { lCellFactory.SetValue(ContentControl.ContentProperty, lColumn.DisplayMemberBinding); // Removing the template selector from the cell as it is now applied in the ContentControl. lColumn.DisplayMemberBinding = null; } // Updating the cell template. lCellDataTemplate.VisualTree = lCellFactory; lColumn.CellTemplate = lCellDataTemplate; } // Adding the column. this.Columns.Add(lColumn); // Notification. if (this.Synchronized != null) { this.Synchronized(); } } }
/// <summary> /// Computes the position of its children inside each child's Margin and calls Arrange on each child. /// </summary> /// <param name="pArrangeSize">Size the GridViewHeaderRowPresenter will assume.</param> protected override Size ArrangeOverride(Size pArrangeSize) { GridViewColumnCollection columns = Columns; double accumulatedWidth = 0.0; double remainingWidth = pArrangeSize.Width; Rect rect; HeadersPositionList.Clear(); if (columns != null) { // Arrange working headers for (int i = 0; i < columns.Count; ++i) { UIElement child = this.GetVisualChild(this.GetVisualIndex(i)) as UIElement; if (child == null) { continue; } ExtendedGridViewColumn column = columns[i] as ExtendedGridViewColumn; // has a given value or 'auto' double childArrangeWidth = Math.Min(remainingWidth, ((column.State == ExtendedGridViewColumnMeasureState.SpecificWidth) ? column.Width : column.DesiredWidth)); // calculate the header rect rect = new Rect(accumulatedWidth, 0.0, childArrangeWidth, pArrangeSize.Height); // arrange header child.Arrange(rect); //Store rect in HeadersPositionList as i-th column position HeadersPositionList.Add(rect); remainingWidth -= childArrangeWidth; accumulatedWidth += childArrangeWidth; } // check width to hide previous header's right half gripper, from the first working header to padding header // only happens after column delete, insert, move //if (_isColumnChangedOrCreated) //{ // for (int i = 0; i < columns.Count; ++i) // { // GridViewColumnHeader header = children[GetVisualIndex(i)] as GridViewColumnHeader; // header.CheckWidthForPreviousHeaderGripper(); // } // _paddingHeader.CheckWidthForPreviousHeaderGripper(); // _isColumnChangedOrCreated = false; //} } // Arrange padding header Debug.Assert(this.PaddingHeader != null, "padding header is null"); rect = new Rect(accumulatedWidth, 0.0, Math.Max(remainingWidth, 0.0), pArrangeSize.Height); this.PaddingHeader.Arrange(rect); this.HeadersPositionList.Add(rect); // if re-order started, arrange floating header & indicator if (this.IsHeaderDragging) { this.FloatingHeader.Arrange(new Rect(new Point(this.DragCurrentPosition.X - this.DragRelativeStartPosition.X, 0), this.HeadersPositionList[this.DragStartColumnIndex].Size)); Point lPos = this.GetHeaderPositionByColumnIndex(this.DragDestColumnIndex); this.DragIndicator.Arrange(new Rect(lPos, new Size(this.DragIndicator.DesiredSize.Width, pArrangeSize.Height))); } return(pArrangeSize); }
/// <summary> /// Override of <seealso cref="FrameworkElement.MeasureOverride" />. /// </summary> /// <param name="pConstraint">Constraint size is an "upper limit" that the return value should not exceed.</param> /// <returns>The GridViewHeaderRowPresenter's desired size.</returns> protected override Size MeasureOverride(Size pConstraint) { double lMaxHeight = 0.0; double lAccumulatedWidth = 0.0; double lConstraintHeight = pConstraint.Height; bool lDesiredWidthListEnsured = false; if (this.Columns != null) { // Measure working headers. for (int i = 0; i < this.Columns.Count; ++i) { // Getting the column header visual element. UIElement lColumnHeader = this.GetVisualChild(this.GetVisualIndex(i)) as UIElement; if (lColumnHeader == null) { continue; } double lChildConstraintWidth = Math.Max(0.0, pConstraint.Width - lAccumulatedWidth); ExtendedGridViewColumn lColumn = this.Columns[i] as ExtendedGridViewColumn; if (lColumn.State == ExtendedGridViewColumnMeasureState.Init) { if (lDesiredWidthListEnsured == false) { this.EnsureDesiredWidthList(); this.LayoutUpdated += this.OnLayoutUpdated; lDesiredWidthListEnsured = true; } lColumnHeader.Measure(new Size(lChildConstraintWidth, lConstraintHeight)); DesiredWidthList[lColumn.ActualIndex] = lColumn.EnsureDesiredWidth(lColumnHeader.DesiredSize.Width); lAccumulatedWidth += lColumn.DesiredWidth; } else if (lColumn.State == ExtendedGridViewColumnMeasureState.Headered || lColumn.State == ExtendedGridViewColumnMeasureState.Data) { //ScrollViewer lParentScrolViewer = this.FindVisualParent<ScrollViewer>(); //if (lParentScrolViewer.ViewportWidth > 0.0) //{ // lColumn.Width = lParentScrolViewer.ViewportWidth / DesiredWidthList.Count; //} lChildConstraintWidth = Math.Min(lChildConstraintWidth, lColumn.DesiredWidth); lColumnHeader.Measure(new Size(lChildConstraintWidth, lConstraintHeight)); lAccumulatedWidth += lColumn.DesiredWidth; } else { // ColumnMeasureState.SpecificWidth. lChildConstraintWidth = Math.Min(lChildConstraintWidth, lColumn.Width); lColumnHeader.Measure(new Size(lChildConstraintWidth, lConstraintHeight)); lAccumulatedWidth += lColumn.Width; } lMaxHeight = Math.Max(lMaxHeight, lColumnHeader.DesiredSize.Height); } } // Measure padding header. this.PaddingHeader.Measure(new Size(0.0, lConstraintHeight)); lMaxHeight = Math.Max(lMaxHeight, this.PaddingHeader.DesiredSize.Height); // Reserve space for padding header next to the last column. lAccumulatedWidth += c_PaddingHeaderMinWidth; // Measure indicator & floating header in re-ordering. if (this.IsHeaderDragging) { // Measure indicator. this.DragIndicator.Measure(pConstraint); // Measure floating header. this.FloatingHeader.Measure(pConstraint); } return(new Size(lAccumulatedWidth, lMaxHeight)); }