Пример #1
0
        /// <summary>
        /// 计算 from,to,并返回总长度。
        ///
        /// 如果在虚拟化模式下,总长度返回 0.
        /// </summary>
        /// <param name="columns"></param>
        /// <returns></returns>
        private double CalcVisibleRange(TreeGridColumnCollection columns)
        {
            this._from = 0;
            this._to   = columns.Count - 1;

            if (!this._isVirtualizing)
            {
                return(0);
            }

            double allWidth         = 0.0;                              //所有列的宽度总和
            double hOffset          = this._rowsPanel.HorizontalOffset; //水平滚动条位置
            double viewPortWidth    = this._rowsPanel.ViewportWidth;    //视窗宽度
            double leftInvisibleSum = 0.0;                              //左边不可见的宽度,逐列累加,直到超过 xOffset
            double visibleSum       = 0.0;                              //当前可见的宽度,逐列累加,直到超过 viewPortWidth
            bool   isVisible        = false;                            //是否当前正在统计不可见的宽度
            bool   stop             = false;                            //是否停止计算可见列,而开始统计所有宽度。

            for (int i = 0, c = columns.Count; i < c; i++)
            {
                var column = columns[i];
                var width  = column.CalculateActualWidth();
                allWidth += width;
                if (stop)
                {
                    continue;
                }

                if (!isVisible)
                {
                    if (leftInvisibleSum + width > hOffset)
                    {
                        this._from = i;
                        visibleSum = leftInvisibleSum + width - hOffset;
                        isVisible  = true;
                    }
                    else
                    {
                        leftInvisibleSum += width;
                    }
                }
                else
                {
                    visibleSum += width;
                    if (visibleSum > viewPortWidth)
                    {
                        this._to = i;
                        stop     = true;
                    }
                }
            }

            return(allWidth);
        }
Пример #2
0
 /// <summary>
 /// 子类在 Measure 时,调用此方法来连接到 TreeGrid,并同步一些必要的属性。
 /// </summary>
 internal void ConnectToGrid()
 {
     if (_treeGrid == null)
     {
         _treeGrid = this.GetVisualParent <TreeGrid>();
         if (_treeGrid != null)
         {
             _columns = _treeGrid.Columns;
             InternalCollectionChangedEventManager.AddListener(_columns, this);
         }
     }
 }
Пример #3
0
 public static void RemoveListener(TreeGridColumnCollection source, IWeakEventListener listener)
 {
     if (source == null)
     {
         throw new ArgumentNullException("source");
     }
     if (listener == null)
     {
         throw new ArgumentNullException("listener");
     }
     InternalCollectionChangedEventManager.CurrentManager.ProtectedRemoveListener(source, listener);
 }
Пример #4
0
        /// <summary>
        /// 保证 desiredList 与 columns 长度一致。
        /// </summary>
        internal static void EnsureDesiredWidthList(ref List <double> desiredList, TreeGridColumnCollection columns)
        {
            if (columns != null)
            {
                int count = columns.Count;

                if (desiredList == null)
                {
                    desiredList = new List <double>(count);
                }

                //对于还没有在 _desiredWidthList 添加对应值的列,都添加相应的数据,
                int num = count - desiredList.Count;
                for (int i = 0; i < num; i++)
                {
                    desiredList.Add(double.NaN);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// 测量所有已经生成的单元格。
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="availableSize"></param>
        /// <returns></returns>
        private Size MeasureChild(TreeGridColumnCollection columns, Size availableSize)
        {
            double maxWidth         = availableSize.Width;
            double maxHeight        = availableSize.Height;
            double rowDesiredHeight = 0.0;                 //行最终需要的高度
            double rowDesiredWidth  = 0.0;                 //行最终需要的宽度
            bool   firstTime        = true;                //是否在 Init 状态下还没有初始化过 DesiredWidthList。
            var    cells            = this.InternalChildren;

            for (int i = this._from, j = 0; i <= this._to; i++, j++)
            {
                var column = columns[i];

                //当前行还可用的宽度
                double rowAvaiableWidth = Math.Max(0, maxWidth - rowDesiredWidth);

                //第一列额外元素需要的宽度
                double headersDesiredWidth = 0;

                #region 测量第一列额外元素需要的宽度

                if (i == 0)
                {
                    //测量 RowHeader
                    if (this.ShowRowHeader)
                    {
                        headersDesiredWidth += this.RowHeaderWidth;
                        rowAvaiableWidth    -= this.RowHeaderWidth;
                        //this._rowHeaderContainer.Measure(new Size(columnWidth, maxHeight));
                        //x += this._rowHeaderContainer.DesiredSize.Width;
                        //columnWidth -= this._rowHeaderContainer.DesiredSize.Width;
                    }

                    //留下 FirstColumnIndent
                    var firstColumnIndent = Math.Min(this.FirstColumnIndent, rowAvaiableWidth);
                    headersDesiredWidth += firstColumnIndent;
                    rowAvaiableWidth    -= firstColumnIndent;

                    //测量 Expander
                    if (this.ShowExpander)
                    {
                        var expander = this.Expander;
                        expander.Measure(new Size(rowAvaiableWidth, maxHeight));
                        headersDesiredWidth += expander.DesiredSize.Width;
                        rowAvaiableWidth    -= expander.DesiredSize.Width;
                    }
                }

                #endregion

                var cell = cells[j];

                //测量单元格
                var state = column.State;
                if (state == ColumnMeasureState.Init || state == ColumnMeasureState.Headered)
                {
                    if (firstTime)
                    {
                        TreeGridHelper.EnsureDesiredWidthList(ref this._desiredWidthList, this._treeGrid.Columns);
                        this.LayoutUpdated += this.OnMeasureLayoutUpdated;
                        firstTime           = false;
                    }

                    cell.Measure(new Size(rowAvaiableWidth, maxHeight));

                    //只有在虚拟化后的当前页面时,才影响动态宽度。
                    if (this._cellsPresenter.IsOnCurrentPage)
                    {
                        //当前列需要的宽度应该是列的宽度加额外元素的宽度。
                        column.EnsureDataWidth(cell.DesiredSize.Width + headersDesiredWidth);
                    }
                    this._desiredWidthList[column.StableIndex] = column.DesiredDataWidth;

                    rowDesiredWidth += column.DesiredDataWidth;
                }
                else
                {
                    var actualWidth = column.CalculateActualWidth();

                    rowAvaiableWidth = Math.Min(rowAvaiableWidth, actualWidth - headersDesiredWidth);

                    cell.Measure(new Size(rowAvaiableWidth, maxHeight));

                    rowDesiredWidth += actualWidth;
                }

                rowDesiredHeight = Math.Max(rowDesiredHeight, cell.DesiredSize.Height);
            }

            rowDesiredWidth += TreeGridHeaderRowPresenter.c_EndPadding;

            this._cellsPresenter.IsOnCurrentPageValid = false;

            return(new Size(rowDesiredWidth, rowDesiredHeight));
        }