Example #1
0
        /// <summary>
        /// 滚动到指定列,等待其生成完毕后,返回该行中的某一个单元格。如果还没有找到,则抛出异常。
        /// </summary>
        /// <param name="column"></param>
        /// <returns></returns>
        public TreeGridCell ScrollToCell(TreeGridColumn column)
        {
            var grid = this.TreeGrid;

            if (grid != null && this.CellsPresenter != null)
            {
                var columnIndex = grid.Columns.IndexOf(column);
                if (columnIndex >= 0)
                {
                    int          i    = 0;
                    TreeGridCell cell = null;
                    while (cell == null && i++ < 1000)//1000 进入防止死循环
                    {
                        grid.BringColumnIntoView(columnIndex);
                        Dispatcher.Invoke(DispatcherPriority.Background, (DispatcherOperationCallback) delegate(object unused)
                        {
                            cell = this.CellsPresenter
                                   .ItemContainerGenerator.ContainerFromIndex(columnIndex) as TreeGridCell;
                            return(null);
                        }, null);
                    }

                    return(cell);
                }
            }

            throw new NotSupportedException("无法滚动到指定的列:" + column.HeaderLabel + ",可能当前行还没有加载完成。");
        }
Example #2
0
        /// <summary>
        /// 尝试开始编辑某一个单元格。
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="editingEventArgs"></param>
        /// <returns></returns>
        internal bool TryEditCell(TreeGridCell cell, RoutedEventArgs editingEventArgs)
        {
            if (this.CanEditCell(cell))
            {
                this.EditCell(cell, editingEventArgs);
                return(true);
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// 尝试找到指定对象的指定单元格。
        /// 如果该行该列正处于虚拟化中,则返回 null。
        /// </summary>
        /// <param name="item"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        public TreeGridCell FindCell(object item, TreeGridColumn column)
        {
            TreeGridCell cell = null;

            var row = this.FindRow(item);

            if (row != null)
            {
                cell = row.FindCell(column);
            }

            return(cell);
        }
Example #4
0
        /// <summary>
        /// 修改表格的编辑状态,并让某个单元格进入编辑状态。
        /// </summary>
        /// <param name="editingCell"></param>
        /// <param name="editingEventArgs">引发此操作的事件参数。可为 null。</param>
        private void EditCellCore(TreeGridCell editingCell, RoutedEventArgs editingEventArgs)
        {
            this._editingItem   = editingCell.Row.DataContext;
            this._editingColumn = editingCell.Column;

            editingCell.SetIsEditingField(true);

            editingCell.FocusOnEditing(editingEventArgs);

            //需要把这个事件处理掉,模仿:DataGridCell.OnAnyMouseButtonDown。
            if (editingEventArgs != null)
            {
                editingEventArgs.Handled = true;
            }
        }
Example #5
0
        private void EditCell(TreeGridCell cell, RoutedEventArgs editingEventArgs)
        {
            //如果当前已经开始编辑某个单元格
            if (this._editingItem != null && this._editingColumn != null)
            {
                if (this._editingColumn != cell.Column || this._editingItem != cell.Row.DataContext)
                {
                    this.ExitCellEditing();

                    this.EditCellCore(cell, editingEventArgs);
                }
            }
            else
            {
                this.EditCellCore(cell, editingEventArgs);
            }
        }
Example #6
0
        /// <summary>
        /// 找到该行中的某一个单元格
        /// </summary>
        /// <param name="column"></param>
        /// <returns></returns>
        public TreeGridCell FindCell(TreeGridColumn column)
        {
            TreeGridCell cell = null;

            if (this.CellsPresenter != null)
            {
                var grid = this.TreeGrid;
                if (grid != null)
                {
                    var columnIndex = grid.Columns.IndexOf(column);
                    if (columnIndex >= 0)
                    {
                        cell = this.CellsPresenter
                               .ItemContainerGenerator.ContainerFromIndex(columnIndex) as TreeGridCell;
                    }
                }
            }

            return(cell);
        }
Example #7
0
        private void PrepareCell(TreeGridCell cell, TreeGridColumn column)
        {
            cell.Column = column;
            if (column.CellStyle != null)
            {
                cell.Style = column.CellStyle;
            }

            cell.UpdateContent(false);

            //IsEditing
            var row = this.Row;

            if (row != null)
            {
                var grid = row.TreeGrid;

                //当前行是表格中正在编辑的行
                if (grid != null && this.DataContext == grid.EditingItem)
                {
                    //整行编辑、或者正在编辑该单元格
                    if (grid.EditingMode == TreeGridEditingMode.Row || column == grid.EditingColumn)
                    {
                        if (cell.Column.CanEdit(cell.DataContext))
                        {
                            cell.SetIsEditingField(true);

                            //this.RestoreEditingContent(cell, column, grid);
                        }
                    }
                }
            }

            //Automation
            var headerLabel = column.HeaderLabel;

            if (!string.IsNullOrEmpty(headerLabel))
            {
                AutomationProperties.SetName(cell, headerLabel);
            }
        }
Example #8
0
        /// <summary>
        /// 返回是否可以成功编辑某个单元格。
        ///
        /// 以下情况下,不能编辑:
        /// * 整个表格不能进行编辑。
        /// * 该单元格所在的列不能进行编辑。
        /// * 表格没有处于 CellEditing 模式下。
        /// * 当前未选择唯一行(单选状态下可编辑)。
        /// </summary>
        /// <param name="cell"></param>
        /// <returns></returns>
        private bool CanEditCell(TreeGridCell cell)
        {
            var success = false;

            if (!this.IsReadOnly && this.EditingMode == TreeGridEditingMode.Cell)
            {
                var column = cell.Column;
                //如果是列是只读状态,就不能进入编辑状态。
                if (cell.Column != null && cell.Column.CanEdit(cell.DataContext))
                {
                    var row           = cell.Row;
                    var selectedItems = this.SelectionModel.InnerItems;
                    //由于点击任何一行的该列都会发生此事件,所以需要检测如果当前只选择了一列
                    if (row != null && selectedItems.Count == 1 && row.DataContext == selectedItems[0])
                    {
                        success = true;
                    }
                }
            }

            return(success);
        }
Example #9
0
        ///// <summary>
        ///// 编辑模式下的编辑元素,保存起来;
        ///// 当单元格再次被生成时,直接使用这些元素而不再次生成。这样可以防止用户信息的丢失。
        /////
        ///// 详见:PrepareCell & ClearCell
        ///// </summary>
        //private Dictionary<TreeGridColumn, UIElement> _editingElements;

        /// <summary>
        /// 当虚拟化 Panel 重新使用一个单元格时,需要尝试恢复它的焦点信息。
        /// </summary>
        /// <param name="cell"></param>
        internal void RestoreEditingCellFocus(TreeGridCell cell)
        {
            var row = this.Row;

            if (row != null)
            {
                var grid = row.TreeGrid;

                if (grid != null && grid.EditingItem != null && grid.EditingItem == this.DataContext)
                {
                    //目前只支持单元格编辑模式下的焦点恢复。
                    if (grid.EditingMode == TreeGridEditingMode.Cell && cell.Column == grid.EditingColumn)
                    {
                        var content = cell.Content as UIElement;
                        if (content != null)
                        {
                            content.Focus();
                        }
                    }
                }
            }
        }
Example #10
0
        //protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        //{
        //    var cell = element as TreeGridCell;

        //    base.ClearContainerForItemOverride(element, item);

        //    this.ReserveEditingContent(cell);
        //}

        //private void ReserveEditingContent(TreeGridCell cell)
        //{
        //    //IsEditing:把编辑控件存储下来。
        //    var row = this.Row;
        //    if (row != null)
        //    {
        //        var grid = row.TreeGrid;
        //        if (grid != null && this.DataContext == grid.EditingItem)
        //        {
        //            //非回收模式下,需要把
        //            if (!grid.IsRecycleMode)
        //            {
        //                if (grid.EditingMode == TreeGridEditingMode.Row || cell.Column == grid.EditingColumn)
        //                {
        //                    if (this._editingElements == null)
        //                    {
        //                        this._editingElements = new Dictionary<TreeGridColumn, UIElement>();
        //                    }
        //                    this._editingElements[cell.Column] = cell.Content as UIElement;
        //                }
        //            }
        //        }
        //    }
        //}

        private void RestoreEditingContent(TreeGridCell cell, TreeGridColumn column, TreeGrid grid)
        {
            ////非回收模式下,为了返回原来的焦点,需要使用之前的编辑控件。
            //if (!grid.IsRecycleMode)
            //{
            //    //如果之前已经生成了编辑控件,则使用老的控件,这样可以继续之前的编辑信息。
            //    if (this._editingElements != null)
            //    {
            //        UIElement content = null;
            //        if (this._editingElements.TryGetValue(column, out content))
            //        {
            //            cell.UpdateContent(content);
            //            //column.PrepareElementForEdit(content as FrameworkElement, null);
            //            //var res = content.Focus();
            //            //Debug.WriteLine(" content.IsVisible:" + content.IsVisible
            //            //    + " content.Focus():" + res
            //            //    + " KeyboardFocus:" + Keyboard.FocusedElement.GetType().FullName
            //            //    );
            //            this._editingElements.Remove(column);
            //        }
            //    }
            //}
        }
Example #11
0
 /// <summary>
 /// 开始编辑某行。
 /// </summary>
 /// <param name="row"></param>
 /// <param name="focusCell">编辑后,应该首先进入编辑状态的单元格。</param>
 public bool TryEditRow(TreeGridRow row, TreeGridCell focusCell)
 {
     return this.TryEditRow(row, null, focusCell);
 }
Example #12
0
 //protected override void ClearContainerForItemOverride(DependencyObject element, object item)
 //{
 //    var cell = element as TreeGridCell;
 //    base.ClearContainerForItemOverride(element, item);
 //    this.ReserveEditingContent(cell);
 //}
 //private void ReserveEditingContent(TreeGridCell cell)
 //{
 //    //IsEditing:把编辑控件存储下来。
 //    var row = this.Row;
 //    if (row != null)
 //    {
 //        var grid = row.TreeGrid;
 //        if (grid != null && this.DataContext == grid.EditingItem)
 //        {
 //            //非回收模式下,需要把
 //            if (!grid.IsRecycleMode)
 //            {
 //                if (grid.EditingMode == TreeGridEditingMode.Row || cell.Column == grid.EditingColumn)
 //                {
 //                    if (this._editingElements == null)
 //                    {
 //                        this._editingElements = new Dictionary<TreeGridColumn, UIElement>();
 //                    }
 //                    this._editingElements[cell.Column] = cell.Content as UIElement;
 //                }
 //            }
 //        }
 //    }
 //}
 private void RestoreEditingContent(TreeGridCell cell, TreeGridColumn column, TreeGrid grid)
 {
     ////非回收模式下,为了返回原来的焦点,需要使用之前的编辑控件。
     //if (!grid.IsRecycleMode)
     //{
     //    //如果之前已经生成了编辑控件,则使用老的控件,这样可以继续之前的编辑信息。
     //    if (this._editingElements != null)
     //    {
     //        UIElement content = null;
     //        if (this._editingElements.TryGetValue(column, out content))
     //        {
     //            cell.UpdateContent(content);
     //            //column.PrepareElementForEdit(content as FrameworkElement, null);
     //            //var res = content.Focus();
     //            //Debug.WriteLine(" content.IsVisible:" + content.IsVisible
     //            //    + " content.Focus():" + res
     //            //    + " KeyboardFocus:" + Keyboard.FocusedElement.GetType().FullName
     //            //    );
     //            this._editingElements.Remove(column);
     //        }
     //    }
     //}
 }
Example #13
0
        private void PrepareCell(TreeGridCell cell, TreeGridColumn column)
        {
            cell.Column = column;
            if (column.CellStyle != null)
            {
                cell.Style = column.CellStyle;
            }

            cell.UpdateContent(false);

            //IsEditing
            var row = this.Row;
            if (row != null)
            {
                var grid = row.TreeGrid;

                //当前行是表格中正在编辑的行
                if (grid != null && this.DataContext == grid.EditingItem)
                {
                    //整行编辑、或者正在编辑该单元格
                    if (grid.EditingMode == TreeGridEditingMode.Row || column == grid.EditingColumn)
                    {
                        if (cell.Column.CanEdit(cell.DataContext))
                        {
                            cell.SetIsEditingField(true);

                            //this.RestoreEditingContent(cell, column, grid);
                        }
                    }
                }
            }

            //Automation
            var headerLabel = column.HeaderLabel;
            if (!string.IsNullOrEmpty(headerLabel)) { AutomationProperties.SetName(cell, headerLabel); }
        }
Example #14
0
        ///// <summary>
        ///// 编辑模式下的编辑元素,保存起来;
        ///// 当单元格再次被生成时,直接使用这些元素而不再次生成。这样可以防止用户信息的丢失。
        ///// 
        ///// 详见:PrepareCell & ClearCell
        ///// </summary>
        //private Dictionary<TreeGridColumn, UIElement> _editingElements;
        /// <summary>
        /// 当虚拟化 Panel 重新使用一个单元格时,需要尝试恢复它的焦点信息。
        /// </summary>
        /// <param name="cell"></param>
        internal void RestoreEditingCellFocus(TreeGridCell cell)
        {
            var row = this.Row;
            if (row != null)
            {
                var grid = row.TreeGrid;

                if (grid != null && grid.EditingItem != null && grid.EditingItem == this.DataContext)
                {
                    //目前只支持单元格编辑模式下的焦点恢复。
                    if (grid.EditingMode == TreeGridEditingMode.Cell && cell.Column == grid.EditingColumn)
                    {
                        var content = cell.Content as UIElement;
                        if (content != null) content.Focus();
                    }
                }
            }
        }
Example #15
0
        /// <summary>
        /// 尝试开始编辑某一个单元格。
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="editingEventArgs"></param>
        /// <returns></returns>
        internal bool TryEditCell(TreeGridCell cell, RoutedEventArgs editingEventArgs)
        {
            if (this.CanEditCell(cell))
            {
                this.EditCell(cell, editingEventArgs);
                return true;
            }

            return false;
        }
Example #16
0
        /// <summary>
        /// 开始编辑某行。
        /// </summary>
        /// <param name="row"></param>
        /// <param name="editingEventArgs">引发编辑的事件参数。</param>
        /// <param name="focusCell">编辑后,应该首先进入编辑状态的单元格。</param>
        internal bool TryEditRow(TreeGridRow row, RoutedEventArgs editingEventArgs, TreeGridCell focusCell)
        {
            var success = false;

            if (!this.IsReadOnly && this.EditingMode == TreeGridEditingMode.Row)
            {
                var item          = row.DataContext;
                var selectedItems = this.SelectionModel.InnerItems;
                //由于点击任何一行的该列都会发生此事件,所以需要检测如果当前只选择了一列
                if (selectedItems.Count == 1 && item == selectedItems[0])
                {
                    //先退出之前行的编辑状态。
                    if (this._editingItem != item)
                    {
                        this.ExitRowEditing();

                        this._editingItem = item;
                    }

                    //focused 表示是否已经有单元格设置了焦点。
                    bool focused   = focusCell != null;
                    var  mouseArgs = editingEventArgs as MouseButtonEventArgs;

                    //设置所有单元格的编辑状态,及焦点。
                    var cells = row.TraverseCells();
                    foreach (var cell in cells)
                    {
                        //设置单元格的编辑状态
                        if (!cell.IsEditing && cell.Column.CanEdit(this._editingItem))
                        {
                            cell.SetIsEditingField(true);
                        }

                        //如果成功设置单元格的编辑状态,而且还没有设置单元格焦点,
                        //那么就通过鼠标的坐标来判断是否需要设置当前单元格的焦点。
                        if (!focused && mouseArgs != null && cell.IsEditing && cell.VisibleOnVirtualizing)
                        {
                            var position     = mouseArgs.GetPosition(cell);
                            var cellPosition = new Rect(cell.RenderSize);
                            if (cellPosition.Contains(position))
                            {
                                cell.FocusOnEditing(editingEventArgs);
                                focused = true;
                            }
                        }
                    }

                    if (focusCell != null)
                    {
                        focusCell.FocusOnEditing(editingEventArgs);
                    }

                    //标记事件已经处理,防止事件继续冒泡导致引发 TreeGridRow.OnGotFocus 事件。
                    if (editingEventArgs != null)
                    {
                        editingEventArgs.Handled = true;
                    }

                    success = true;
                }
            }

            return(success);
        }
Example #17
0
        /// <summary>
        /// 修改表格的编辑状态,并让某个单元格进入编辑状态。
        /// </summary>
        /// <param name="editingCell"></param>
        /// <param name="editingEventArgs">引发此操作的事件参数。可为 null。</param>
        private void EditCellCore(TreeGridCell editingCell, RoutedEventArgs editingEventArgs)
        {
            this._editingItem = editingCell.Row.DataContext;
            this._editingColumn = editingCell.Column;

            editingCell.SetIsEditingField(true);

            editingCell.FocusOnEditing(editingEventArgs);

            //需要把这个事件处理掉,模仿:DataGridCell.OnAnyMouseButtonDown。
            if (editingEventArgs != null)
            {
                editingEventArgs.Handled = true;
            }
        }
Example #18
0
        /// <summary>
        /// 开始编辑某行。
        /// </summary>
        /// <param name="row"></param>
        /// <param name="editingEventArgs">引发编辑的事件参数。</param>
        /// <param name="focusCell">编辑后,应该首先进入编辑状态的单元格。</param>
        internal bool TryEditRow(TreeGridRow row, RoutedEventArgs editingEventArgs, TreeGridCell focusCell)
        {
            var success = false;

            if (!this.IsReadOnly && this.EditingMode == TreeGridEditingMode.Row)
            {
                var item = row.DataContext;
                var selectedItems = this.SelectionModel.InnerItems;
                //由于点击任何一行的该列都会发生此事件,所以需要检测如果当前只选择了一列
                if (selectedItems.Count == 1 && item == selectedItems[0])
                {
                    //先退出之前行的编辑状态。
                    if (this._editingItem != item)
                    {
                        this.ExitRowEditing();

                        this._editingItem = item;
                    }

                    //focused 表示是否已经有单元格设置了焦点。
                    bool focused = focusCell != null;
                    var mouseArgs = editingEventArgs as MouseButtonEventArgs;

                    //设置所有单元格的编辑状态,及焦点。
                    var cells = row.TraverseCells();
                    foreach (var cell in cells)
                    {
                        //设置单元格的编辑状态
                        if (!cell.IsEditing && cell.Column.CanEdit(this._editingItem))
                        {
                            cell.SetIsEditingField(true);
                        }

                        //如果成功设置单元格的编辑状态,而且还没有设置单元格焦点,
                        //那么就通过鼠标的坐标来判断是否需要设置当前单元格的焦点。
                        if (!focused && mouseArgs != null && cell.IsEditing && cell.VisibleOnVirtualizing)
                        {
                            var position = mouseArgs.GetPosition(cell);
                            var cellPosition = new Rect(cell.RenderSize);
                            if (cellPosition.Contains(position))
                            {
                                cell.FocusOnEditing(editingEventArgs);
                                focused = true;
                            }
                        }
                    }

                    if (focusCell != null)
                    {
                        focusCell.FocusOnEditing(editingEventArgs);
                    }

                    //标记事件已经处理,防止事件继续冒泡导致引发 TreeGridRow.OnGotFocus 事件。
                    if (editingEventArgs != null) editingEventArgs.Handled = true;

                    success = true;
                }
            }

            return success;
        }
Example #19
0
        /// <summary>
        /// 返回是否可以成功编辑某个单元格。
        /// 
        /// 以下情况下,不能编辑:
        /// * 整个表格不能进行编辑。
        /// * 该单元格所在的列不能进行编辑。
        /// * 表格没有处于 CellEditing 模式下。
        /// * 当前未选择唯一行(单选状态下可编辑)。
        /// </summary>
        /// <param name="cell"></param>
        /// <returns></returns>
        private bool CanEditCell(TreeGridCell cell)
        {
            var success = false;

            if (!this.IsReadOnly && this.EditingMode == TreeGridEditingMode.Cell)
            {
                var column = cell.Column;
                //如果是列是只读状态,就不能进入编辑状态。
                if (cell.Column != null && cell.Column.CanEdit(cell.DataContext))
                {
                    var row = cell.Row;
                    var selectedItems = this.SelectionModel.InnerItems;
                    //由于点击任何一行的该列都会发生此事件,所以需要检测如果当前只选择了一列
                    if (row != null && selectedItems.Count == 1 && row.DataContext == selectedItems[0])
                    {
                        success = true;
                    }
                }
            }

            return success;
        }
Example #20
0
 /// <summary>
 /// 尝试通知本树型控件编辑某个单元格。
 /// </summary>
 /// <param name="cell"></param>
 /// <returns>返回是否成功进入编辑状态</returns>
 public bool TryEditCell(TreeGridCell cell)
 {
     return this.TryEditCell(cell, null);
 }
Example #21
0
        /// <summary>
        /// 在编辑控件按 Tab 切换到下一列
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="moveNext">是向后编辑还是向前编辑。</param>
        /// <param name="e"></param>
        /// <param name="firstStarted"></param>
        internal void EditNextColumnOnTabKey(TreeGridCell cell, bool moveNext, KeyEventArgs e, TreeGridColumn firstStarted)
        {
            var grid = this.TreeGrid;
            var columns = grid.Columns;

            var index = columns.IndexOf(this);
            index += moveNext ? 1 : -1;

            //循环:如果是最后一个,则使用第一个;如果是第一个,则使用最后一个。
            if (index >= columns.Count)
            {
                index = 0;
            }
            else if (index < 0)
            {
                index = columns.Count - 1;
            }

            //尝试编辑
            var row = cell.Row;
            if (row != null)
            {
                var nextColumn = columns[index] as TreeGridColumn;

                //如果要编辑的单元格和起始单元格是同一个格子,则已经循环了一次,不需要继续了。
                if (nextColumn == firstStarted) return;

                grid.BringColumnIntoView(index);
                var nextCell = row.FindCell(nextColumn);
                if (nextCell != null)
                {
                    bool success = false;
                    if (grid.EditingMode == TreeGridEditingMode.Cell)
                    {
                        success = grid.TryEditCell(nextCell, e);
                    }
                    else
                    {
                        //行模式下,只是把焦点移到下一个单元格即可。
                        if (nextCell.IsEditing)
                        {
                            nextCell.FocusOnEditing(e);

                            success = true;
                        }
                    }

                    if (success)
                    {
                        e.Handled = true;
                        return;
                    }

                    //如果 nextCell 编辑失败,并且不是循环第二次,则继续编辑下一个。
                    nextColumn.EditNextColumnOnTabKey(nextCell, moveNext, e, firstStarted);
                }
            }
        }
Example #22
0
 /// <summary>
 /// 尝试通知本树型控件编辑某个单元格。
 /// </summary>
 /// <param name="cell"></param>
 /// <returns>返回是否成功进入编辑状态</returns>
 public bool TryEditCell(TreeGridCell cell)
 {
     return(this.TryEditCell(cell, null));
 }
Example #23
0
        private void EditCell(TreeGridCell cell, RoutedEventArgs editingEventArgs)
        {
            //如果当前已经开始编辑某个单元格
            if (this._editingItem != null && this._editingColumn != null)
            {
                if (this._editingColumn != cell.Column || this._editingItem != cell.Row.DataContext)
                {
                    this.ExitCellEditing();

                    this.EditCellCore(cell, editingEventArgs);
                }
            }
            else
            {
                this.EditCellCore(cell, editingEventArgs);
            }
        }
Example #24
0
 /// <summary>
 /// 开始编辑某行。
 /// </summary>
 /// <param name="row"></param>
 /// <param name="focusCell">编辑后,应该首先进入编辑状态的单元格。</param>
 public bool TryEditRow(TreeGridRow row, TreeGridCell focusCell)
 {
     return(this.TryEditRow(row, null, focusCell));
 }
Example #25
0
 public MTTGCellAutomationPeer(TreeGridCell owner)
     : base(owner)
 {
 }
Example #26
0
 public MTTGCellAutomationPeer(TreeGridCell owner) : base(owner)
 {
 }
Example #27
0
        /// <summary>
        /// 在编辑控件按 Tab 切换到下一列
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="moveNext">是向后编辑还是向前编辑。</param>
        /// <param name="e"></param>
        /// <param name="firstStarted"></param>
        internal void EditNextColumnOnTabKey(TreeGridCell cell, bool moveNext, KeyEventArgs e, TreeGridColumn firstStarted)
        {
            var grid    = this.TreeGrid;
            var columns = grid.Columns;

            var index = columns.IndexOf(this);

            index += moveNext ? 1 : -1;

            //循环:如果是最后一个,则使用第一个;如果是第一个,则使用最后一个。
            if (index >= columns.Count)
            {
                index = 0;
            }
            else if (index < 0)
            {
                index = columns.Count - 1;
            }

            //尝试编辑
            var row = cell.Row;

            if (row != null)
            {
                var nextColumn = columns[index] as TreeGridColumn;

                //如果要编辑的单元格和起始单元格是同一个格子,则已经循环了一次,不需要继续了。
                if (nextColumn == firstStarted)
                {
                    return;
                }

                grid.BringColumnIntoView(index);
                var nextCell = row.FindCell(nextColumn);
                if (nextCell != null)
                {
                    bool success = false;
                    if (grid.EditingMode == TreeGridEditingMode.Cell)
                    {
                        success = grid.TryEditCell(nextCell, e);
                    }
                    else
                    {
                        //行模式下,只是把焦点移到下一个单元格即可。
                        if (nextCell.IsEditing)
                        {
                            nextCell.FocusOnEditing(e);

                            success = true;
                        }
                    }

                    if (success)
                    {
                        e.Handled = true;
                        return;
                    }

                    //如果 nextCell 编辑失败,并且不是循环第二次,则继续编辑下一个。
                    nextColumn.EditNextColumnOnTabKey(nextCell, moveNext, e, firstStarted);
                }
            }
        }