1
yhj
2024-07-24 5e5d945e91568b973faa27d8ab0bcef99fc4a6c5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#region
 
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
 
#endregion
 
namespace CSFrameworkV5.Library.CommonClass
{
    /// <summary>
    ///     GridView移动表格单元管理类, 最后版本:2014-12-30
    /// </summary>
    public class GridMovetor
    {
        /// <summary>
        ///     根据GridView内置有焦点的控件,获取父级GridView
        /// </summary>
        /// <param name="activeControl">当前焦点的控件</param>
        /// <returns></returns>
        private static GridView GetGridViewByFocusEditor(Control activeControl)
        {
            while (activeControl.Parent != null)
            {
                if (activeControl.Parent is GridControl)
                    return (GridView)((GridControl)activeControl.Parent)
                        .FocusedView;
 
                activeControl = activeControl.Parent;
            }
 
            return null;
        }
 
        /// <summary>
        ///     检查当前控件是否GridView内置有焦点的控件
        /// </summary>
        /// <param name="activeControl">当前焦点的控件</param>
        /// <returns></returns>
        public static bool IsGridViewEditorFocus(Control activeControl)
        {
            var isEditor = activeControl is TextBoxBase;
            var view = GetGridViewByFocusEditor(activeControl);
            return isEditor && view != null;
        }
 
        /// <summary>
        ///     是否最后可编辑的列
        /// </summary>
        /// <param name="view">GridView</param>
        /// <param name="focusedColumn">当前焦点的列</param>
        /// <returns></returns>
        public static bool IsLastEditableColumn(GridView view,
            GridColumn focusedColumn)
        {
            var idx = view.VisibleColumns.IndexOf(focusedColumn);
 
            for (var i = view.VisibleColumns.Count - 1; i >= 0; i--)
            {
                var col = view.VisibleColumns[i];
 
                //忽略不可编辑Column
                if (!col.OptionsColumn.AllowEdit) continue;
 
                if (idx != i) return false; //非最后一个可编辑Column
 
                return true;
            }
 
            return true;
        }
 
        /// <summary>
        ///     移动到下一个可编辑的列
        /// </summary>
        /// <param name="currentCol"></param>
        /// <param name="e"></param>
        public static void MoveNextColumn(GridColumn currentCol)
        {
            for (var i = currentCol.VisibleIndex + 1;
                 i < currentCol.View.VisibleColumns.Count;
                 i++)
            {
                var colTemp = currentCol.View.VisibleColumns[i];
                if (colTemp.OptionsColumn.AllowEdit)
                {
                    currentCol.View.FocusedColumn = colTemp;
                    break;
                }
            }
        }
 
        /// <summary>
        ///     移动到下一个可编辑的列, 若是当前行的最后一列,则定位下一行的第一个可编辑栏位.
        /// </summary>
        /// <param name="view">GridView</param>
        /// <param name="activeControl">当前焦点的控件</param>
        /// <param name="e"></param>
        public static void MoveNextColumnOrRow(GridView view,
            GridColumn currentCol, KeyPressEventArgs e)
        {
            //若是当前行的最后一列,则定位下一行的第一个可编辑栏位.
            if (IsLastEditableColumn(view, currentCol))
            {
                if (view.FocusedRowHandle + 1 < view.RowCount)
                {
                    view.MoveNext();
                    view.FocusedColumn = view.VisibleColumns[0];
                    e.Handled = true;
                }
            }
            else
            {
                //在当前行定位下一个可编辑栏位.
                MoveNextColumn(view.FocusedColumn);
                e.Handled = true;
            }
        }
 
        /// <summary>
        ///     处理表格KeyDown事件。
        ///     <para>1.按回车或Tab键自动跳到下一个栏位.</para>
        ///     <para>2.处理在最后一条记录的最后一栏按回车键新增一条记录.</para>
        /// </summary>
        public static void OnGridViewKeyDown(object sender, KeyEventArgs e)
        {
            if (!(e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab)) return;
 
            if (sender is GridView)
            {
                var view = (GridView)sender;
                var grid = view.GridControl;
 
                var isLastCol = IsLastEditableColumn(view, view.FocusedColumn);
                var isLastRow = view.FocusedRowHandle == view.RowCount - 1;
 
                //不是最后可编辑列, 则移至下一列
                if (isLastCol == false || isLastRow == false)
                {
                    MoveNextColumnOrRow(view, view.FocusedColumn,
                        new KeyPressEventArgs((char)Keys.Enter));
                    e.Handled = true;
                    return; //任务完成,不处理以下任何事务
                }
 
                //最后一条记录的最后一列,自动添加记录
                if (isLastRow && isLastCol && view.OptionsBehavior.Editable)
                    if (view.GridControl.EmbeddedNavigator.Buttons.CustomButtons
                            .Count > 0)
                    {
                        var addButtonIndex = 0;
                        NavigatorButtonBase addButton =
                            view.GridControl.EmbeddedNavigator.Buttons
                                .CustomButtons[addButtonIndex];
                        view.GridControl.EmbeddedNavigator.Buttons.DoClick(
                            addButton);
                        view.FocusedColumn =
                            view.VisibleColumns[0]; //新增记录后,将焦点移动到第一列
                        e.Handled = true;
                    }
            }
        }
    }
}