#region using System; using System.Collections; using System.Data; using System.Windows.Forms; using CSFrameworkV5.Core; using DevExpress.XtraGrid.Views.Grid; #endregion namespace CSFrameworkV5.Library { public partial class frmRowPositionAdjustor : Form { private static Hashtable _HS = new Hashtable(); private IRowAdjustor _Adjustor; public frmRowPositionAdjustor() { InitializeComponent(); } private static void AddMenu(GridView gv, string sortFieldName) { //添加分隔条菜单项 gv.GridControl.ContextMenuStrip.Items.Add("-"); //添加菜单项 var img = new frmRowPositionAdjustor().imageList1.Images[0]; var menuItem = gv.GridControl.ContextMenuStrip.Items.Add("调整行位置", img, On_Adjustor_Click); menuItem.Name = "menuRowAdjustor"; menuItem.Tag = new RowAdjustorMenuItemTag { GridView = gv, SortFieldName = sortFieldName }; } private void btnFirst_Click(object sender, EventArgs e) { _Adjustor.ToFirst(); } private void btnLast_Click(object sender, EventArgs e) { _Adjustor.ToLast(); } private void btnNext_Click(object sender, EventArgs e) { _Adjustor.ToNext(); } private void btnPrior_Click(object sender, EventArgs e) { _Adjustor.ToPrior(); } private void btnReset_Click(object sender, EventArgs e) { _Adjustor.Reset(); } /// /// 打开排序调整界面 /// /// 父级窗体 /// 表格组件 /// 排序字段名称 /// 自动关闭排序调整窗体,C/S开发框架调用必须设为True,其他调用设为False public static void Execute(Form owner, GridView grid, string sortFieldName, bool autoClose = false) { if (owner == null) throw new Exception("必须指定父级窗体!"); var form = new frmRowPositionAdjustor(); form._Adjustor = new GridViewRowAdjustor(grid, sortFieldName); form.TopMost = true; form.Owner = owner; form.SetPosition(grid); form.Show(); //自动关闭排序调整窗体 if (autoClose) { owner.FormClosing += Owner_FormClosing; owner.Deactivate += Owner_Deactivate; _HS.Add(owner, form); } } //关闭当前窗体(Adjustor Form) private void frmRowPositionAdjustor_FormClosed(object sender, FormClosedEventArgs e) { if (_HS.Contains(Owner)) _HS.Remove(Owner); } private static void On_Adjustor_Click(object sender, EventArgs e) { var tag = (sender as ToolStripItem).Tag as RowAdjustorMenuItemTag; Execute(tag.GridView.GridControl.FindForm(), tag.GridView, tag.SortFieldName, true); } //父级窗体失去焦点事件 private static void Owner_Deactivate(object sender, EventArgs e) { if (_HS.Contains(sender as Form)) { (_HS[sender as Form] as frmRowPositionAdjustor).Close(); _HS.Remove(sender as Form); } } //父级窗体关闭事件 private static void Owner_FormClosing(object sender, FormClosingEventArgs e) { if (_HS.Contains(sender as Form)) { (_HS[sender as Form] as frmRowPositionAdjustor).Close(); _HS.Remove(sender as Form); } } /// /// 注册表格组件,自动创建弹出菜单 /// /// 表格组件 /// 排序字段名称 public static void Register(GridView gv, string sortFieldName) { var menu = gv.GridControl.ContextMenuStrip; if (menu == null) { gv.GridControl.ContextMenuStrip = new ContextMenuStrip(); AddMenu(gv, sortFieldName); } else { var items = menu.Items.Find("menuRowAdjustor", true); if (items.Length == 0) AddMenu(gv, sortFieldName); } } //设置窗体的显示位置 private void SetPosition(GridView grid) { var form = grid.GridControl.FindForm(); StartPosition = FormStartPosition.Manual; //int X = grid.GridControl.Left + form.Left+150; //int Y = grid.GridControl.Top + form.Top; //this.Location = new Point(X, Y); var P = grid.GridControl.PointToScreen(grid.GridControl.Location); P.X += 100; P.Y += 20; Location = P; } } public class RowAdjustorMenuItemTag { public GridView GridView { get; set; } public string SortFieldName { get; set; } } /// /// 位置调整接口 /// public interface IRowAdjustor { /// /// 重置排序序号 /// decimal Reset(); void ToFirst(); void ToLast(); void ToNext(); void ToPrior(); } /// /// DevExpress GridView表格记录行位置调整器 - C/S框架网 - www.cscode.net /// public class GridViewRowAdjustor : IRowAdjustor { private int _FirstSortID = 1; //默认初始序号(第一条记录的序号) private GridView _GridView; private string _SortFieldName; //用于排序的字段名称 public GridViewRowAdjustor(GridView view, string sortFieldName) { _GridView = view; _SortFieldName = sortFieldName; //设置排序字段 DataSource.DefaultView.Sort = sortFieldName + " ASC"; CheckSortValue(true); } private DataTable DataSource => _GridView.GridControl.DataSource as DataTable; public decimal Reset() { if (_GridView.RowCount == 0) return 0; var i = _FirstSortID; //初始序号 //枚举DataView的记录,重新设置序号 //不能直接枚举DataView.Table对象的记录,这是原始记录 DataRow row; var enu = DataSource.DefaultView.GetEnumerator(); while (enu.MoveNext()) { row = (enu.Current as DataRowView).Row; //跳过被删除的记录 if (row.RowState != DataRowState.Deleted) { row[_SortFieldName] = i; i++; } } _GridView.GridControl.RefreshDataSource(); _GridView.FocusedRowHandle = 0; return i; } public void ToFirst() { //当前记录是第一条记录,不处理 if (_GridView.FocusedRowHandle == 0) return; //当前记录 var R = _GridView.GetFocusedDataRow(); //原始第1条记录的序号 var R_Old = _GridView.GetDataRow(0); var sort = GetSortValue(R_Old[_SortFieldName]); R[_SortFieldName] = sort / 2; //当前记录的序号=原始第1条记录的序号/2,所以排在前面 _GridView.GridControl.RefreshDataSource(); } public void ToLast() { //当前记录是最后一条记录,不处理 if (_GridView.FocusedRowHandle == _GridView.RowCount - 1) return; //当前记录 var R = _GridView.GetFocusedDataRow(); //原始最后一条记录的序号 var R_Old = _GridView.GetDataRow(_GridView.RowCount - 1); var sort = GetSortValue(R_Old[_SortFieldName]); R[_SortFieldName] = sort + 1; //最后序号+1,排序最后 _GridView.GridControl.RefreshDataSource(); } public void ToNext() { //当前记录是最后一条记录,不处理 if (_GridView.FocusedRowHandle == _GridView.RowCount - 1) return; //当前记录 var R1 = _GridView.GetFocusedDataRow(); var sort1 = GetSortValue(R1[_SortFieldName]); //取下1条记录 var R2 = _GridView.GetDataRow(_GridView.FocusedRowHandle + 1); var sort2 = GetSortValue(R2[_SortFieldName]); //交换序号 R1[_SortFieldName] = sort2; R2[_SortFieldName] = sort1; _GridView.GridControl.RefreshDataSource(); } public void ToPrior() { //当前记录是第一条记录,不处理 if (_GridView.FocusedRowHandle == 0) return; //当前记录 var R1 = _GridView.GetFocusedDataRow(); var sort1 = GetSortValue(R1[_SortFieldName]); //取上一条记录 var R2 = _GridView.GetDataRow(_GridView.FocusedRowHandle - 1); var sort2 = GetSortValue(R2[_SortFieldName]); //交换序号 R1[_SortFieldName] = sort2; R2[_SortFieldName] = sort1; _GridView.GridControl.RefreshDataSource(); } /// /// 检测排序字段的值 /// /// True:若检测排序字段的值为空,自动重置排序ID, False:不排序 /// private bool CheckSortValue(bool resetIfNullValue) { var hasNullValue = false; foreach (DataRow R in DataSource.Rows) if (R[_SortFieldName] == DBNull.Value //空值 || R[_SortFieldName].ToStringEx().Trim() == "" //空值 || Convert.ToDecimal(R[_SortFieldName].ToStringEx() .Trim()) == 0) //等于0 { hasNullValue = true; break; } if (hasNullValue && resetIfNullValue) Reset(); return hasNullValue; } private decimal GetSortValue(object fieldValue) { if (fieldValue == DBNull.Value) return 0; return Convert.ToDecimal(fieldValue); } } }