#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);
}
}
}